I ran into something that I didn’t know was an issue with Get-WmiObject. I have been using Get-WmiObject for quite sometime so this was a shock to me. I had written a script to grab the description from servers and dump them to a gridview.
I wanted to run this on 1400 servers. Meaning know it was going to take awhile. When I ended up running it, it took too long, actually waaaay to long. The reason? Some of the Get-WmiObject calls were hanging for what ever reason. No problem I thought lets assign the timeout argument to the Get-WmiObject? Where is the timeout argument? ??? After a bit of searching and reading I learned there is no way to set a timeout to the Get-WmiObject commandlet.
After some more reading I learned that the best way to handing this is to setup the Get-WmiObject as a Job. The job can handle the Get-WmiObject process and if it takes longer than you think it should, kill the job and move on.
I don’t have the old way I was running the script but this is the new way.. I tried to comment it as much as I could.
# try this and catch it if it fails
try {
# Set the try to stop if it error out
$ErrorActionPreference = 'Stop'
# start the Job and assign it to a variable..
# -scriptBlock -- assign the -scriptblock argument to show what to run.. this is where the
# get-wmiobject is run. This is encapsualted in {}
# param -- set the param to pass along the server name from the -ArgumentList to the
# Get-WmiObject commandlet
# -ArgumentList pass in the server information.
# | Wait-Job -Timeout 2 - This tells the job to wait for 2 seconds.
$job = start-job -scriptBlock {param ([string]$server) Get-WmiObject -Class Win32_OperatingSystem -ComputerName $server } -ArgumentList $server | Wait-Job -Timeout 2
# This dumps out the job information to a variable to use later
$results = $job | Receive-Job | select Description
# If the Job state is not completed then it was and error, so write out an error for the
# try/catch to catch.
if ($job.state -ne "Completed") {Write-Error "Error"}
# This is the where we put the variables into an array.
$List += [pscustomobject]@{
'ComputerName' = $server
'Description' = $results.Description
}
}
catch {
#catch if there is an error and if there is write that there was one in the lsit array..
$List += [pscustomobject]@{
'ComputerName' = $server
'Description' = "Error"
}
}
Here is the full script.
#get the list of servers to scan from serverlist.txt
$serverlist = "C:\scripts\computers.txt"
$List = @()
$i = 0
$fileCount = 0
#get the count of servers for updates to the user.
$fileCount = (Get-Content $serverlist | Measure-Object).Count
#Loop the server list.
foreach ($server in Get-Content $serverlist) {
#increment the number of records proccessed
$i++
#Write to the screen whats happening.
Write-Progress -activity "Connecting to server $server" -status "Scanning: $i of $($fileCount)" -percentComplete (($i / $fileCount) * 100)
# try this and catch it if it fails
try {
# Set the try to stop if it error out
$ErrorActionPreference = 'Stop'
# start the Job and assign it to a variable..
# -scriptBlock -- assign the -scriptblock argument to show what to run.. this is where the get-wmiobject is run. This is encapsualted in {}
# param -- set the param to pass along the server name from the -ArgumentList to the Get-WmiObject commandlet
# -ArgumentList pass in the server information.
# | Wait-Job -Timeout 2 - This tells the job to wait for 2 seconds.
$job = start-job -scriptBlock {param ([string]$server) Get-WmiObject -Class Win32_OperatingSystem -ComputerName $server } -ArgumentList $server | Wait-Job -Timeout 2
# This dumps out the job information to a variable to use later
$results = $job | Receive-Job | select Description
# If the Job state is not completed then it was and error, so write out an error for the try/catch to catch.
if ($job.state -ne "Completed") {Write-Error "Error"}
# This is the where we put the variables into an array.
$List += [pscustomobject]@{
'ComputerName' = $server
'Description' = $results.Description
}
}
catch {
#catch if there is an error and if there is write that there was one in the lsit array..
$List += [pscustomobject]@{
'ComputerName' = $server
'Description' = "Error"
}
}
}
$List | Out-GridView
My Admin Journal: Powershell – Hanging Get-Wmiobject >>>>> Download Now
ReplyDelete>>>>> Download Full
My Admin Journal: Powershell – Hanging Get-Wmiobject >>>>> Download LINK
>>>>> Download Now
My Admin Journal: Powershell – Hanging Get-Wmiobject >>>>> Download Full
>>>>> Download LINK Zj