Is PowerShell Installed?

By now you may have PowerShell installed on more than a few machines. Maybe you even have the PowerShell CTP installed somewhere. Do you remember where you’ve installed PowerShell? Could someone else have installed PowerShell on a system without your knowledge? Perhaps an eager user?

I put together a PowerShell function you can use to check if PowerShell is installed on a remote system.

Function Get-PowerShellInstall {
Param ([string]$computer="localhost")

#registry hive constants
$HKLM=2147483650
$HKCU=2147483649
$HKCR=2147483648
$HKEY_USERS=2147483651

#there is no provision for alternate credentials
$Reg = [WMIClass]"\$computer\root\default:StdRegProv"

$basePath="software\microsoft\powershell\1"
$ShellPath="shellids\Microsoft.PowerShell"
$EnginePath="PowerShellEngine"

$InstallPath=$reg.GetStringValue($HKLM,(Join-Path $basePath $ShellPath),"path").svalue

#only get other values if able to get a value for $InstallPath
if ($InstallPath) {

$Installed=$True
$ExecutionPolicy=$reg.GetStringValue($HKLM,(Join-Path $basePath $ShellPath),"ExecutionPolicy").svalue
#if ExecutionPolicy key is missing then assume Restricted
if (-not $ExecutionPolicy) {
$ExecutionPolicy="Restricted"
}
$PowerShellVersion=$Reg.GetStringValue($HKLM,(Join-Path $basePath $EnginePath),"PowerShellVersion").svalue
$RunTimeVersion=$Reg.GetStringValue($HKLM,(Join-Path $basePath $EnginePath),"RunTimeVersion").svalue

}
else {

$InstallPath=""
$Installed=$False
$ExecutionPolicy=""
$PowerShellVersion=""
$RunTimeVersion=""

}

$obj=New-Object PSObject
$obj | Add-Member -MemberType NoteProperty -Name "Computer" -Value $computer.ToUpper()
$obj | Add-Member -MemberType NoteProperty -Name "Installed" -Value $Installed
$obj | Add-Member -MemberType NoteProperty -Name "InstallPath" -Value $InstallPath
$obj | Add-Member -MemberType NoteProperty -Name "ExecutionPolicy" -Value $ExecutionPolicy
$obj | Add-Member -MemberType NoteProperty -Name "Version" -Value $PowerShellVersion
$obj | Add-Member -MemberType NoteProperty -Name "RunTimeVersion" -Value $RunTimeVersion

write $obj

}

Don’t try to copy and paste the function from the blog entry as it screws up some formatting details. I’ve attached it as a text file.

The script uses WMI and the StdRegProv to remotely connect to a specified computer’s registry. To accomplish this we create an instance of a WMIClass object using the [WMIClass] type adapter.

$Reg = [WMIClass]"\$computer\root\default:StdRegProv"

One drawback is that there is no way to specify alternate credentials so you can only connect to remote systems with your current credentials.

Once connected we can read installation information from the registry. Instead of returning basic information, the function returns a custom object. When you run the function you should get a result like this:

Computer : LOCALHOST
Installed : True
InstallPath : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
ExecutionPolicy : RemoteSigned
Version : 1.0
RunTimeVersion : v2.0.50727

But because the function returns an object and can accept input you can do things like this:

cat servers.txt | % { get-powerShellInstall $_ | where {$_.Installed}} | format-table Computer,InstallPath,ExecutionPolicy,Version -auto

Now you should be able to easily find out where PowerShell is installed and how it is configured.

Technorati Tags: , , ,