Wednesday, April 1, 2009

Sorry for the absence. Did your heart grow fonder?

For the few, and by few I mean very few, that read these posts I want to come right out and say sorry.  Sorry I've been away so long!  I took a new job last year with <insert major global conglomeration> and have been completely swamped the past few months writing new code in HTA format for a new solution, possibly to be patented.  We'll have to see how that goes.

In celebration of the hard work I've been doing, I have decided to start some code examples on HTA programming and how you can add a spiffy GUI to your existing scripts.  Neat?  You bet.  Stay tuned and I promise not to leave you hanging.

-Corey

Function GetChassisType

Just ran across the need to determine what kind of machine I am running a script on.  I needed to detect whether or not the machine was a laptop or desktop.  Just so happens that WMI provides a nifty class for this.

As you check out the function below, notice some of the really odd chassis types available.  How many of you have a "pizza box" or "lunchbox" chassis?

 

Function getChassisType(sstrComputer)
'Global: Dim intChassisType to reference by number
'Returns a string value of the type.    
    
    Set sobjWMIService = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate}!\\" & sstrComputer & "\root\cimv2")
    
    Set colChassis = sobjWMIService.ExecQuery _
        ("Select ChassisTypes from Win32_SystemEnclosure")
    
    For Each objChassis in colChassis
        For i = Lbound(objChassis.ChassisTypes) to Ubound(objChassis.ChassisTypes)
            intChassisType =  objChassis.ChassisTypes(i)
        Next
    Next
    
    Select Case intChassisType
        Case 1
            getChassisType = "Other"
        Case 2
            getChassisType = "Unknown"
        Case 3
            getChassisType = "Desktop"
        Case 4
            getChassisType = "Low Profile Desktop"
        Case 5
            getChassisType = "Pizza Box"
        Case 6
            getChassisType = "Mini Tower"
        Case 7
            getChassisType = "Tower"
        Case 8
            getChassisType = "Portable"
        Case 9
            getChassisType = "Laptop"
        Case 10
            getChassisType = "Notebook"
        Case 11
            getChassisType = "Hand Held"
        Case 12
            getChassisType = "Docking Station"
        Case 13
            getChassisType = "All in One"
        Case 14
            getChassisType = "Sub Notebook"
        Case 15
            getChassisType = "Space-Saving"
        Case 16
            getChassisType = "Lunch Box"
        Case 17
            getChassisType = "Main System Chassis"
        Case 18
            getChassisType = "Expansion Chassis"
        Case 19
            getChassisType = "SubChassis"
        Case 20
            getChassisType = "Bus Expansion Chassis"
        Case 21
            getChassisType = "Peripheral Chassis"
        Case 22
            getChassisType = "Storage Chassis"
        Case 23
            getChassisType = "Rack Mount Chassis"
        Case 24
            getChassisType = "Sealed-Case PC"
        Case Else
            getChassisType = "Unknown"
    End Select
    Set sobjWMIService = Nothing     
 
End Function

 

Enjoy the code and as always, let me know if this script helps you out!

 

-Corey Thomas

MCSE/MCSA/MCDBA/Security+,CIW Associate

Tuesday, October 21, 2008

Registry and the dreaded HKCU

Good to be back in the swing of things.  Last month I spent some time at DisneyWorld and had a blast.  When I came back, another hot issue on the table for this script master to solve.

I can't tell you how many times I've need to add/delete/modify a key in the HKEY Current Users hive on remote machines.  WMI does provide a registry object that you can use and it does include an HKCU hive...  However, as some of you may know, when you access that HKCU hive, it's not the actual HKCU but rather the HKCU for the account you are using to run the script.  Not very useful.

 

There are several ways to get in the actual HKCU but my personal method is a three step process.  We already know that there is another hive, HKEY Users, that contains all the users on that machine. And we have no problem getting into that hive remotely.  But, that hive uses SID values to identify each unique user.  My process is to identify the current user, get the SID for that user, then drill into the HKU\SID hive. 

 

Step One: Get the current user of a machine.

For this I use a function (as I usually do):

 

Function GetCurrentUser2(sstrComputer)
 
    On Error Resume Next
    Dim sstrKeyPath,sstrCU,sstrCUD,sstrCurrentUser,sstrCurrentUserDomain
    
    sHKEY_LOCAL_MACHINE = &H80000002
    
    Set sobjRegistry = GetObject("winmgmts:\\" & sstrComputer & "\root\default:StdRegProv")
    
    sstrKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon"
    sstrCU = "DefaultUserName"
    sstrCUD = "DefaultDomainName"
    
    sobjRegistry.GetStringValue sHKEY_LOCAL_MACHINE, sstrKeyPath, sstrCU, sstrCurrentUser
    sobjRegistry.GetStringValue sHKEY_LOCAL_MACHINE, sstrKeyPath, sstrCUD, sstrCurrentUserDomain
    
    
    
    GetCurrentUser2 = sstrCurrentUserDomain & "\" & sstrCurrentUser
 
 
End Function

 

Simply pass the computer name and it returns the user as "domain\logon".  This works fairly well unless you have some sort of security policy that is removing that value from the remote registry. You'll notice that my function is called GetCurrentUsers2.  The original function I used looked up the explorer.exe and found the owner of that process.  That worked, but not 100%.

Now that we have the current user stored as a "domain\logon" variable, we can then query the domain to get the associated SID for that user.  Again, another function.

 

Function GetSIDFromUser(UserName)
'Input: UserName as domain\logon
'Output: SID
 
  Dim DomainName, Result, WMIUser
 
  If InStr(UserName, "\") > 0 Then
    DomainName = Mid(UserName, 1, InStr(UserName, "\") - 1)
    UserName = Mid(UserName, InStr(UserName, "\") + 1)
  Else
    DomainName = CreateObject("WScript.Network").UserDomain
  End If
 
  On Error Resume Next
  Set WMIUser = GetObject("winmgmts:{impersonationlevel=impersonate}!" _
    & "/root/cimv2:Win32_UserAccount.Domain='" & DomainName & "'" _
    & ",Name='" & UserName & "'")
  If Err = 0 Then Result = WMIUser.SID Else Result = ""
  On Error GoTo 0
 
  GetSIDFromUser = Result
End Function

 

This function will query the domain for the user and return the unique SID for the user.  Now you can put two and two together and access HKEY_Users\SID to get the HKCU hive on a machine.

 

I have some functions for accessing the registry remotely.  Each of them rely on these two functions for support when accessing HKCU.  I will posting up new articles with those functions soon.  In the meantime, if you have any questions on these functions or suggestions for new ones, please let me know by clicking the email icon below.

-Corey