Author Posts

April 14, 2014 at 7:08 am

Hi,

I'm having some issue with following script:


$Computers = get-adcomputer -filter * -searchbase "ou=computers,dc=domain,dc=com" | foreach-object {$_.name}

foreach ($computer in $Computers)

{get-windowskey -targets $computer}

Get-windowskey is a function I have loaded into my environment which takes the name of a pc, stated with the param -targets, and returns the Windows version and product key. When I run the above script with hard coded $Computers, it runs great. However, running the above gives me the below error, any advice?

Thanks in advance


Cannot convert value "\\CAND8TQ14J\root\default:stdRegProv" to type "System.Management.ManagementClass". Error: "The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)"
At C:\Powershell\GetProductKeyFunction.ps1:11 char:9
+ $wmi = [WMIClass]"\\$target\root\default:stdRegProv"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastToWMIClass

You cannot call a method on a null-valued expression.
At C:\Powershell\GetProductKeyFunction.ps1:12 char:9
+ $data = $wmi.GetBinaryValue($hklm,$regPath,$regValue)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull

Cannot index into a null array.
At C:\Powershell\GetProductKeyFunction.ps1:13 char:9
+ $binArray = ($data.uValue)[52..66]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray

April 14, 2014 at 7:15 am

Your ForEach-Object is a bit of an odd way to do what you're after...


Get-ADComputer -filter * | Select -Expand Name

Is a bit more common.

The errors are coming from inside your Get-WindowsKey function. Without seeing it, it's a bit difficult to guess what might be wrong. But, the error "RPC server is unavailable" suggests that it isn't connecting to the computer listed in $target.

I suspect you might be able to query the same info more easily by using the Win32_OperatingSystem class, too. That'd eliminate needing to mess with the registry, if the info you need is in there.

April 14, 2014 at 7:22 am

Hey Don, thank you for your response. I'll make that amendment to the script, thanks for the suggestion.

I noticed as soon as I posted that the error looked to be stemming from the function itself. It's one I grabbed from the net.

Thanks for your time and insight.

Here is the function:

function Get-WindowsKey {
## function to retrieve the Windows Product Key from any PC
## by Jakob Bindslet (jakob@bindslet.dk)
param ($targets = ".")
$hklm = 2147483650
$regPath = "Software\Microsoft\Windows NT\CurrentVersion"
$regValue = "DigitalProductId"
Foreach ($target in $targets) {
$productKey = $null
$win32os = $null
$wmi = [WMIClass]"\\$target\root\default:stdRegProv"
$data = $wmi.GetBinaryValue($hklm,$regPath,$regValue)
$binArray = ($data.uValue)[52..66]
$charsArray = "B","C","D","F","G","H","J","K","M","P","Q","R","T","V","W","X","Y","2","3","4","6","7","8","9"
## decrypt base24 encoded binary data
For ($i = 24; $i -ge 0; $i--) {
$k = 0
For ($j = 14; $j -ge 0; $j--) {
$k = $k * 256 -bxor $binArray[$j]
$binArray[$j] = [math]::truncate($k / 24)
$k = $k % 24
}
$productKey = $charsArray[$k] + $productKey
If (($i % 5 -eq 0) -and ($i -ne 0)) {
$productKey = "-" + $productKey
}
}
$win32os = Get-WmiObject Win32_OperatingSystem -computer $target
$obj = New-Object Object
$obj | Add-Member Noteproperty Computer -value $target
$obj | Add-Member Noteproperty Caption -value $win32os.Caption
$obj | Add-Member Noteproperty CSDVersion -value $win32os.CSDVersion
$obj | Add-Member Noteproperty OSArch -value $win32os.OSArchitecture
$obj | Add-Member Noteproperty BuildNumber -value $win32os.BuildNumber
$obj | Add-Member Noteproperty RegisteredTo -value $win32os.RegisteredUser
$obj | Add-Member Noteproperty ProductID -value $win32os.SerialNumber
$obj | Add-Member Noteproperty ProductKey -value $productkey
$obj
}
}

April 14, 2014 at 7:30 am

Looks like all you really need is some error handling. If the ([WMIClass]"\\$target\root\default:stdRegProv") expression throws an error such as RPC Server is Unavailable, there's really no point in trying to run the rest of the code for that particular target.

April 15, 2014 at 12:49 am

Thanks Dave, I'll take a look at what is needed and how to implement it. Price you pay for using someone elses code I guess!

Thanks again.

April 15, 2014 at 2:19 am

Just to give an update, I managed to get it working. I changed the param for the function to except get-content, and added some error handling. Working out the rest of the kinks, but pretty happy with what I have so far. Thanks to you both for pointing me in the right direction.

Regards,
Doug