PowerShell Ezine, Logon Scripts

Guy's Scripting Ezine 63 - Registry Software Info

Contents for Ezine 63 - Registry Software Information

This week’s secret

This week I experienced scripting from the other side of the fence.  Shane has kindly sent me a script.  Later I will share it's beauty with you.  But for now I want to empathise with how you must feel when I send you a script.  When Shane send me the script I copied and pasted it, then changed a few variables and bingo it worked.  Isn't it just magic when a new script executes and output results.

I have to confess that it took me all evening to figure out EXACTLY how Shane's script works.  That experience reminded me of how everyone believes that their script is self evident and that anyone else should immediately understand how they work.

ˆ

Mission to read installed software from the registry

Now I do remember promising a script that would write to the registry, but please bear with me until next week.  Shane's script is so apt, is such a logical follow-on and has so many interesting features that I simply have to share it with you this week.  In particular, last week's script was simple and introductory, whereas Shane's script is meaty and advanced.

The purpose of Shane's script is to retrieve information about software installed, on not one, but all your network computers (That will take time to collect).  The cunning feature is that it actually enumerates the Uninstall information in the registry.  Do you see the logic?  If the software has put Uninstall entries in the registry then it must be INSTALLED.  Now I know this is not a 100% certainty, but it's good enough for our purpose.


If you are looking for handy network utilities, try some of the free downloads at Tools4Ever


Example 1 - To extract software information from the registry

Instructions

  1. Copy and paste the script below into notepad. Alternatively, get a trial copy of OnScript.
  2. Save the file with .vbs extension e.g. ReadSoftware.vbs
  3. Create a folder called c:\logs
  4. strDomain = "CP.com"      ' Your Domain
  5. Double click and then check the message box
  6. You may like to run Regedit and navigate to this section
    HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall
  7. Special Note.  Be patient, it could take a long time to find all the computers in the domain.
  8. If the script takes longer than 7 minutes then consider UN remarking lines 31 and 33.  Be sure and change YOURPC to = the hostname of your machine.
    Line 31:  '  If UCase(pcObject.name) = "YOURPC" Then ' N.B. Edit YOURPC
    Line 32:  objPCTXTFile.WriteLine pcObject.Name
    Line 33:  '  End if
  9. Finally note that what ever computer name you use should be IN CAPITALS.

 

 

' RegSoftware.vbs
' VBScript to read software installed from the registry.
' Author Shane Rudy
' Modified by Guy Thomas http://computerperformance.co.uk
' Version 3.3 - February 13th 2005
' ----------------------------------------'

' Declare the constants
Const HKLM = &H80000002 ' HKEY_LOCAL_MACHINE
Const REG_SZ = 1 ' String value in registry (Not DWORD)
Const ForReading = 1
Const ForWriting = 2

' Set File objects...
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objDictionary = CreateObject("Scripting.Dictionary")
Set objDictionary2 = CreateObject("Scripting.Dictionary")

' Set string variables
strDomain = "CP.com" ' Your Domain
strPCsFile = "DomainPCs.txt" '
strPath = "C:\logs\" ' Create this folder
strUninstall = "C:\logs\Uninstall.txt"
WScript.Echo "If script takes 7 mins + " & vbCr & "Un-comment lines 31,33"

' Get list of domain PCs - Using above variables.
Set objPCTXTFile = objFSO.OpenTextFile(strPath & strPCsFile, ForWriting, True)
Set objDomain = GetObject("WinNT://" & strDomain) ' Note LDAP does not work
objDomain.Filter = Array("Computer")
For Each pcObject In objDomain
' If UCase(pcObject.name) = "YOURPC" Then ' N.B. Edit YOURPC CASE SENSITIVE
objPCTXTFile.WriteLine pcObject.Name
' End if
Next
objPCTXTFile.close

' Read list of computers from strPCsFile into objDictionary
Set readPCFile = objFSO.OpenTextFile(strPath & strPCsFile, ForReading)
i = 0
Do Until readPCFile.AtEndOfStream
strNextLine = readPCFile.Readline
objDictionary.Add i, strNextLine
i = i + 1
Loop
readPCFile.Close

' Run the procedure defined in the Sub routine GetInstalledSoftware()

For each DomainPC in objDictionary
strComputer = objDictionary.Item(DomainPC)
GetInstalledSoftware()
Next

Set objFilesystem = Nothing

WScript.echo "Finished Scanning Network check : " & strPath

objFSO.DeleteFile(strUninstall)
objFSO.DeleteFile(strPath & strPCsFile)

Sub GetInstalledSoftware()

On Error Resume next

' WMI connection to the operating system note StdRegProv
Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\default:StdRegProv")

If Err <> "0" Then
Exit Sub
End If

' Registry paths which hold the Uninstall information.
unKeyPath = "Software\Microsoft\Windows\CurrentVersion\Uninstall"
unValueName = ("DisplayName")

' Enumerate Registry subkey paths for uninstall. Note arrSubKeys
objReg.EnumKey HKLM, unKeyPath, arrSubKeys
Set objTextFile1 = objFSO.OpenTextFile(strUninstall, ForWriting,True)
For Each Subkey in arrSubKeys
objTextFile1.WriteLine (unKeyPath & "\"& subkey & (Enter))
Next

' Read Registry info stored in the strUninstall file
Set objTextFile3 = objFSO.OpenTextFile(strUninstall, ForReading)

'pipe the uninstall paths from the uninstall.txt file into a second dictionary
i = 0
Do Until objTextFile3.AtEndOfStream
strNextLine = objTextFile3.Readline
objDictionary2.Add i, strNextLine
i = i + 1
Loop

' These paths are used in the filenames you see in the strPath
pcName = "SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName\"
pcNameValueName = "ComputerName"
userPath = "Software\Microsoft\Windows NT\CurrentVersion\Winlogon\"
userValueName = "DefaultUserName"
objReg.GetStringValue HKLM,pcName,pcNameValueName,pcValue
objReg.GetStringValue HKLM,userPath,userValueName,userValue

' Build up the filename found in the strPath
strFileName = UserValue & "_" & "On" & "_" & PCValue & "_" & "Software" _
& year(date()) & right("0" & month(date()),2) _
& right("0" & day(date()),2) & ".txt"

' Write each PC's software info file...
Set objTextFile2 = objFSO.OpenTextFile(strPath & strFileName, ForWriting, True)
' Writing info to the corresponding Software info file...
objTextFile2.WriteLine(vbCRLF & "==============================" & vbCRLF & _
"Current Installed Software " & vbCRLF & Time & vbCRLF & Date _
& vbCRLF & "Software For:" & "" & userValue & vbCRLF & "On System:" _
& "" & pcValue & vbCRLF & "----------------------------------------" & vbCRLF)

' First enumeration also clean up if error exists (Second enumaration omitted)
For Each objItem in objDictionary2
strKeyPath = objDictionary2.Item(objItem)
objReg.GetStringValue HKLM ,strKeyPath, unValueName, strValue
objTextFile2.WriteLine (strValue)
If Err Then
objDictionary2.Remove(objItem)
End If
Next

End Sub

wscript.Quit
 

 

ˇ

Learning Points

Note 1:  The heart of the script is on line 49.  What this section does is get each computer in the dictionary and run the sub routine called GetInstalledSoftware(). This extracts the install / uninstall information from the registry:
For each DomainPC in objDictionary
strComputer = objDictionary.Item(DomainPC)
GetInstalledSoftware()
Next

Note 2:  Last week's script used .regread to extract information from a registry key, this week Shane's script uses WMI on line 66, note the method StdRegProv
Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\default:StdRegProv")

Note 3:  One of the many useful qualities of this script is that it outputs the information to a file, rather than echoing to screen.  Take a moment to run through the occurrences of FSO (File System Object) and see how the text output is created and controlled.

Note 4: Where I went wrong was to change WinNT to LDAP on line 28.  Wrong move Guy.  WinNT is correct here, it extracts the simple ComputerName = ALAN.  (note upper case).  Firstly, LDAP needed additional information the CN= or OU= where the computers were stored, and secondly the output was un-usable, CN=ALAN did not work (O.K I could have trimmed it but by then I could see that LDAP was not as good as WinNT here.

Challenges

Shane's original script had extra sections which I removed for the sake of brevity.  (I also wanted to reduce the complexity of the script if possible.  See the full script here

Summary - Reading the Registry

Thanks to Shane we have a wonderful, purposeful script which connects to the registry, extracts information about the installed software, writes the names of the programs to TextFile in C:\logs\.

Computer Training Software - Recommended Training VideosGuy Thomas recommends Computer Training Software

Their topics and material are ideal for getting you started with VBScript.  The videos are easy to follow and you can control the pace.  Try their free demo material and then see if you want to buy the full package. See more about VB Script Training CD.


^


Google
Web  This website

Solarwinds IpMonitorIs Your Server Running Slowly?

Check with SolarWinds ipMonitor

Analyze your network with ipMonitor.  Get a free evaluation copy, and monitor the performance of the servers on your network.
Free Download of SolarWinds ipMonitor