You are on page 1of 8

USEFUL SCRIPTS FOR SOFTWARE LICENCE AUDITING by Andrea Jones

@allaboutclait

The Powershell scripts should be saved as .ps1 files and then run using
Powershell ISE. Any one-line scripts can be run from the Powershell
command prompt (best to right-click Powershell and select Run as
administrator). I imported the results using Excels data import facility
ensuring any columns were formatted as text if they were likely to lose
leading zeroes or other information.

Powershell script to find all active directory PCs with OS and service pack
using Quest active directory powershell snap-in (available from Dells
website at http://tinyurl.com/oukq26q tick the box to continue to
download, Im afraid its a bit of a hassle to get hold of otherwise):

Add-PSSnapin Quest.ActiveRoles.ADManagement
Get-QADComputer | Export-Csv -Path C:\pcs.csv

Powershell script to find all installed applications using a source .csv file
containing computers to query (you will need to cross-check the results to
make sure all machines responded):

##################################################
########################

$comments = @'
Author: Kevin Higgins
Date: 1/24/2014
Purpose: Remotely pull a list of all programs installed on a
windows-based computer.

Misc Info: This script is rewritten from the code in the URL below.
Difference include:

1. Fixes original code issue of $computername ($computername =


$pc.computername) not working.

2. Added checking for 64-bit programs.

3. Added a "32 or 64 bit" column

4. Additional "search" example for -match & -eq


5. Clears the $reg variable before processing each computer. (Prevents programs
installed on ComputerA from showing as installed on ComputerB if ComputerB is
inaccessible.)

6. Skips loop processing if a computer's registry is NOT accessible. (this is the 'trap'.
I got tired of seeing red text due to inaccessible computers.)

Reference
URL: http://blogs.technet.com/b/heyscriptingguy/archive/2011/11/13/use-
powershell-to-quickly-find-installed-software.aspx

Prerequisite1: Remote registry services running.

If not, the from admin cmd prompt, run these two commands

sc \\computername config remoteregistry start= auto

sc \\computername start remoteregistry

Prerequisite2: ComputersToCheck.csv

Cell A1 = computername (The text "computername".)

Cell A2 = DESKTOP01 (The name of a real computer.)

Cell A3 = DESKTOP02 (The name of a real computer.)

Registry keys checked:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersio
n\Uninstall

'@

##################################################
########################

clear-host

#Note: Edit the two lines below.

$computers = Import-Csv "C:\pshell\computerlist.csv"


$DomainName = ".domain.com"

$array = @()

foreach($pc in $computers) {

#$pc = $computers[0]

$computername = $pc.computername

$computernameFQDN = $computername + $DomainName;

write-host -f cyan "`nStarting scan on computer " -nonewline; write-host -f


green "$computername."

#Define the variable to hold the location of Currently Installed Programs

$UninstallKey32 =
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"

$UninstallKey64 =
"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"

#Create an instance of the Registry Object and open the HKLM base key

$reg = $null

trap {; Continue};
[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',
$computernameFQDN) | out-null

if ($? -eq $False) {write-host -f red "`t Error accessing $computername.";


continue}

$reg =
[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',
$computernameFQDN)

#Drill down into the Uninstall key using the OpenSubKey Method
$regkey32 = $null

$regkey64 = $null

$regkey32 = $reg.OpenSubKey($UninstallKey32)

$regkey64 = $reg.OpenSubKey($UninstallKey64)

#Retrieve an array of string that contain all the subkey names

$subkeys32 = $null

$subkeys64 = $null

$subkeys32 = $regkey32.GetSubKeyNames()

$subkeys64 = $regkey64.GetSubKeyNames()

#32bit Open each Subkey and use GetValue Method to return the
required values for each

foreach($key in $subkeys32){

$thisKey = $UninstallKey32+"\\"+$key

$thisSubKey = $reg.OpenSubKey($thisKey)

#if (-not $thisSubKey.getValue("DisplayName")) { continue }

$obj = New-Object PSObject

$obj | Add-Member -MemberType NoteProperty -Name


"ComputerName" -Value $computername

$obj | Add-Member -MemberType NoteProperty -Name "32 or


64 bit" -Value " 32-bit"

$obj | Add-Member -MemberType NoteProperty -Name


"DisplayName" -Value $($thisSubKey.GetValue("DisplayName"))

$obj | Add-Member -MemberType NoteProperty -Name


"DisplayVersion" -Value $($thisSubKey.GetValue("DisplayVersion"))
$obj | Add-Member -MemberType NoteProperty -Name
"InstallLocation" -Value $($thisSubKey.GetValue("InstallLocation"))

$obj | Add-Member -MemberType NoteProperty -Name


"Publisher" -Value $($thisSubKey.GetValue("Publisher"))

$array += $obj

#$array.length

#64bit Open each Subkey and use GetValue Method to return the
required values for each

foreach($key in $subkeys64){

$thisKey = $UninstallKey64+"\\"+$key

$thisSubKey = $reg.OpenSubKey($thisKey)

#if (-not $thisSubKey.getValue("DisplayName")) { continue }

$obj = New-Object PSObject

$obj | Add-Member -MemberType NoteProperty -Name


"ComputerName" -Value $computername

$obj | Add-Member -MemberType NoteProperty -Name "32 or


64 bit" -Value " 64-bit"

$obj | Add-Member -MemberType NoteProperty -Name


"DisplayName" -Value $($thisSubKey.GetValue("DisplayName"))

$obj | Add-Member -MemberType NoteProperty -Name


"DisplayVersion" -Value $($thisSubKey.GetValue("DisplayVersion"))

$obj | Add-Member -MemberType NoteProperty -Name


"InstallLocation" -Value $($thisSubKey.GetValue("InstallLocation"))

$obj | Add-Member -MemberType NoteProperty -Name


"Publisher" -Value $($thisSubKey.GetValue("Publisher"))

$array += $obj
}

#$array.length

1..5 | % {write-host "`n"}

#See all installed programs

$array | Where-Object { $_.DisplayName } | select ComputerName, "32 or


64 bit", DisplayName, DisplayVersion, Publisher | ft -auto >
"H:/pshell/installedsoftwareMar2016-TS3.txt"

#Search for "iTunes", "Google", "Google Chrome"

#$array | Where-Object { $_.DisplayName -match "iTunes"} | select


ComputerName, "32 or 64 bit", DisplayName, DisplayVersion, Publisher | ft -auto

#$array | Where-Object { $_.DisplayName -match "Google"} | select


ComputerName, "32 or 64 bit", DisplayName, DisplayVersion, Publisher | ft -auto

#$array | Where-Object { $_.DisplayName -match "Google Chrome"} |


select ComputerName, "32 or 64 bit", DisplayName, DisplayVersion, Publisher | ft
-auto

#Check for a specific installation from "Microsoft Updates"

#$array | Where-Object { $_.DisplayName -match "KB2687455"} | select


ComputerName, "32 or 64 bit", DisplayName, DisplayVersion, Publisher | ft -auto

#Search for EXACT text of "Google Chrome"

#$array | Where-Object { $_.DisplayName -eq "Google Chrome"} | select


ComputerName, "32 or 64 bit", DisplayName, DisplayVersion, Publisher | ft -auto

##################################################
########################

Powershell command to find SQL server instances (right-click powershell


and select Run as Administrator):
[System.Data.Sql.SqlDataSourceEnumerator]::Instance.GetDataSources()

Exchange management shell queries to run on the mail server:

Get all mailboxes and output to text file:

Get-Mailbox ResultSize Unlimited > C:\mailboxes.txt

Output all archive mailboxes to text file:

Get-Mailbox archive ResultSize Unlimited > c:\archivemailboxes.txt

Vbs script for finding users with dial-in permission from


http://www.thedailyadmin.com/2009/02/vbscript-to-find-users-in-active.html?m=1

'***************************************************
'This script will pull all users that have Dial-in
'access from Active Directory and the OU the account
'is in and writes the values out to the file RRAS_VPN_Users.txt
'***************************************************
Option Explicit
On Error Resume Next
Const ADS_SCOPE_SUBTREE = 2
Dim objConnection, objCommand, objRootDSE
Dim objRecordSet, ou
Dim namingContext, fso, outFile
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection

set objRootDSE = getobject("LDAP://RootDSE")


namingContext = objRootDSE.Get("defaultNamingContext")
set objRootDSE = nothing

Set fso = CreateObject("Scripting.FileSystemObject")


Set outFile = fso.CreateTextFile("RRAS_VPN_Users.txt", True)
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
objCommand.CommandText = _
"SELECT Name FROM 'LDAP://" & namingContext & _
"' WHERE objectCategory='user' " & _
"AND msNPAllowDialin = TRUE"

Set objRecordSet = objCommand.Execute


objRecordSet.MoveFirst
Do Until objRecordSet.EOF
' Call function to find OU from computer name
ou = getOUByUserName(objRecordSet.Fields("Name").Value)
outFile.WriteLine(objRecordSet.Fields("Name").Value & _
",'" & ou & "'")
objRecordSet.MoveNext
Loop
outFile.Close

WScript.Echo "Complete"

WScript.Quit

function getOUByUserName(byval UserName)

' *** Function to find ou/container of user object ***


DIM namingContext, ldapFilter, ou
DIM cn, cmd, rs
DIM objRootDSE
set objRootDSE = getobject("LDAP://RootDSE")
namingContext = objRootDSE.Get("defaultNamingContext")
set objRootDSE = nothing

ldapFilter = "<LDAP://" & namingContext & _


">;(&(objectCategory=User)(name=" & userName & "))" & _
";distinguishedName;subtree"

set cn = createobject("ADODB.Connection")
set cmd = createobject("ADODB.Command")
cn.open "Provider=ADsDSOObject;"
cmd.activeconnection = cn
cmd.commandtext = ldapFilter

set rs = cmd.execute
if rs.eof <> true and rs.bof <> true then
ou = rs(0)
ou = mid(ou,instr(ou,",")+1,len(ou)-instr(ou,","))
getOUByuserName = ou

end if
rs.close
cn.close
end function

You might also like