Hi All,
I had this script working fine but it wouldn’t capture machines that can’t be reached/firewall is preventing access. It just throws out an error “Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)” I have attempted to add a try catch block but just can’t get it to work.
Get-ADComputer -Filter {enabled -eq "true" -and
OperatingSystem -ne "Windows XP Professional" -and
OperatingSystem -ne "Windows 7 Professional" -and
OperatingSystem -ne "Mac OS X" -and
OperatingSystem -ne "Windows 8.1 Pro" -and
OperatingSystem -ne "Windows 8 Pro" -and
OperatingSystem -ne "Windows 7 Ultimate" -and
OperatingSystem -ne "OnTap" -and
OperatingSystem -ne "Windows 7 Enterprise" -and
Operatingsystem -ne "unknown" -and
OperatingSystem -ne "Windows 8 Enterprise" -and
OperatingSystem -ne "Windows 8.1 Enterprise" -and
OperatingSystem -ne "Windows 7 Professional N" -and
OperatingSystem -ne "Windows Vista™ Business" -and
OperatingSystem -ne "Windows 8 Pro with Media Center" -and
OperatingSystem -ne "Windows 2000 Professional" -and
OperatingSystem -ne "Windows Developer Preview" -and
OperatingSystem -ne "SLES"
} |
Select-Object -First 20 |
Foreach-Object {
Try {
Get-WmiObject -Class win32_service -ComputerName $_.name
}
Catch {
write-warning "Error occured: $_.name" | Out-File c:\temp\Servererrors.txt -Append
}
}|
Where-Object -FilterScript { $_.StartName -ne "LocalSystem"-and
$_.StartName -ne "NT AUTHORITY\localService" -and
$_.StartName -ne "NT AUTHORITY\NetworkService" -and
$_.startname -ne "NT AUTHORITY\LOCAL SERVICE" -and
$_.startname -ne "NT AUTHORITY\NETWORK SERVICE" -and
$_.startname -ne ".\ctx_cpsvcuser" -and
$_.startname -ne ".\Ctx_StreamingSvc"
} |
Select-Object -Property __server,DisplayName,startname
Any guidance would be greatly appreciated.
Alex
Does something like this work - someone else might be able to offer something more elegant, but the idea would be to break your script apart a little bit. Really the above is a single command.
I couldn’t actually check the WMI bit because i have WMI enabled everywhere.
$computers = Get-ADComputer -Filter { enabled -eq "true" -and
OperatingSystem -ne "Windows XP Professional" -and
OperatingSystem -ne "Windows 7 Professional" -and
OperatingSystem -ne "Mac OS X" -and
OperatingSystem -ne "Windows 8.1 Pro" -and
OperatingSystem -ne "Windows 8 Pro" -and
OperatingSystem -ne "Windows 7 Ultimate" -and
OperatingSystem -ne "OnTap" -and
OperatingSystem -ne "Windows 7 Enterprise" -and
Operatingsystem -ne "unknown" -and
OperatingSystem -ne "Windows 8 Enterprise" -and
OperatingSystem -ne "Windows 8.1 Enterprise" -and
OperatingSystem -ne "Windows 7 Professional N" -and
OperatingSystem -ne "Windows Vista™ Business" -and
OperatingSystem -ne "Windows 8 Pro with Media Center" -and
OperatingSystem -ne "Windows 2000 Professional" -and
OperatingSystem -ne "Windows Developer Preview" -and
OperatingSystem -ne "SLES" }
foreach ($computer in $computers) {
$test = Test-Connection $computer.Name -Count 1 -ErrorAction SilentlyContinue -ErrorVariable TestConnectionError
if ($TestConnectionError -eq $null) {
$wmi = Get-WmiObject -Class win32_service -ComputerName $_.name -ErrorAction SilentlyContinue -ErrorVariable WMIError
if ($wmiError -eq $null) {
$wmi | Where-Object -FilterScript { $_.StartName -ne "LocalSystem"-and
$_.StartName -ne "NT AUTHORITY\localService" -and
$_.StartName -ne "NT AUTHORITY\NetworkService" -and
$_.startname -ne "NT AUTHORITY\LOCAL SERVICE" -and
$_.startname -ne "NT AUTHORITY\NETWORK SERVICE" -and
$_.startname -ne ".\ctx_cpsvcuser" -and
$_.startname -ne ".\Ctx_StreamingSvc"
} | Select-Object -Property __server,DisplayName,startname
} #end inner if
else {
$wmiError | out-file "c:\temp\wmi.log"
Write-Warning "Unable to connect to $($computer.name)"
} #end else
} #end if
else {
$TestConnectionError | out-file "c:\temp\test.log"
}
} #end foreach
Sorry i’ve made a few mistakes in there. Looks like it would never enter the if statement because $testconnectionError -eq $null doesn’t seem to work… but anyway this one should now work and log.
$computers = Get-ADComputer -Filter { enabled -eq "true" -and
OperatingSystem -ne "Windows XP Professional" -and
OperatingSystem -ne "Windows 7 Professional" -and
OperatingSystem -ne "Mac OS X" -and
OperatingSystem -ne "Windows 8.1 Pro" -and
OperatingSystem -ne "Windows 8 Pro" -and
OperatingSystem -ne "Windows 7 Ultimate" -and
OperatingSystem -ne "OnTap" -and
OperatingSystem -ne "Windows 7 Enterprise" -and
Operatingsystem -ne "unknown" -and
OperatingSystem -ne "Windows 8 Enterprise" -and
OperatingSystem -ne "Windows 8.1 Enterprise" -and
OperatingSystem -ne "Windows 7 Professional N" -and
OperatingSystem -ne "Windows Vista™ Business" -and
OperatingSystem -ne "Windows 8 Pro with Media Center" -and
OperatingSystem -ne "Windows 2000 Professional" -and
OperatingSystem -ne "Windows Developer Preview" -and
OperatingSystem -ne "SLES" }
foreach ($computer in $computers) {
$test = Test-Connection $computer.Name -Count 1 -ErrorAction SilentlyContinue -ErrorVariable TestConnectionError
if ($TestConnectionError.Count -eq 0) {
Get-WmiObject -Class win32_service -ComputerName $computer.DNSHostName | Where-Object -FilterScript { $_.StartName -ne "LocalSystem"-and
$_.StartName -ne "NT AUTHORITY\localService" -and
$_.StartName -ne "NT AUTHORITY\NetworkService" -and
$_.startname -ne "NT AUTHORITY\LOCAL SERVICE" -and
$_.startname -ne "NT AUTHORITY\NETWORK SERVICE" -and
$_.startname -ne ".\ctx_cpsvcuser" -and
$_.startname -ne ".\Ctx_StreamingSvc"
} | Select-Object -Property __server,DisplayName,startname -ErrorAction SilentlyContinue -ErrorVariable WMIError
if ($wmiError.Count -gt 0) {
$wmiError | out-file "c:\temp\wmi.log"
Write-Warning "Unable to connect to $($computer.name)"
} #end inner if
} #end if
else {
$TestConnectionError | out-file "c:\temp\test.log" -Append
}
} #end foreach
donj
August 6, 2014, 10:46pm
4
If you’re worried about not getting the the WMI service, then a ping alone won’t confirm connectivity.
On your Get-WMiObject call, change your ErrorAction to Stop. SilentlyContinue will merely suppress the error. Then, use a Try/Catch block.
try {
Get-WMiObject -class whatever -computer whatever -ErrorAction stop
} catch {
# log the error here
}
The problem in the initial script is that the default error action is Continue, which doesn’t produce a trappable exception. Setting the error action to Stop makes the Try/Catch work as I think you expected it to.
oh i see, i did wonder why some would take the try / catch block and others would not.
Ah yes that’s true regarding ping. Probably not worth the added complication in that case.
Thanks guys. This gives me stuff to work with, i’ll let you know how i get on.
Alex
So got the script to work with both your help so thank you.
Here is the finished script, might even look at making this into a function at some point
$computers = Get-ADComputer -Filter { enabled -eq "true" -and
OperatingSystem -ne "Windows XP Professional" -and
OperatingSystem -ne "Windows 7 Professional" -and
OperatingSystem -ne "Mac OS X" -and
OperatingSystem -ne "Windows 8.1 Pro" -and
OperatingSystem -ne "Windows 8 Pro" -and
OperatingSystem -ne "Windows 7 Ultimate" -and
OperatingSystem -ne "OnTap" -and
OperatingSystem -ne "Windows 7 Enterprise" -and
Operatingsystem -ne "unknown" -and
OperatingSystem -ne "Windows 8 Enterprise" -and
OperatingSystem -ne "Windows 8.1 Enterprise" -and
OperatingSystem -ne "Windows 7 Professional N" -and
OperatingSystem -ne "Windows Vista™ Business" -and
OperatingSystem -ne "Windows 8 Pro with Media Center" -and
OperatingSystem -ne "Windows 2000 Professional" -and
OperatingSystem -ne "Windows Developer Preview" -and
OperatingSystem -ne "SLES" }
foreach ($computer in $computers) {
TRY {
Get-WmiObject -Class win32_service -ComputerName $computer.DNSHostName -ErrorAction Stop |
Where-Object -FilterScript { $_.StartName -ne "LocalSystem"-and
$_.StartName -ne "NT AUTHORITY\localService" -and
$_.StartName -ne "NT AUTHORITY\NetworkService" -and
$_.startname -ne "NT AUTHORITY\LOCAL SERVICE" -and
$_.startname -ne "NT AUTHORITY\NETWORK SERVICE" -and
$_.startname -ne ".\ctx_cpsvcuser" -and
$_.startname -ne ".\Ctx_StreamingSvc"
} |
Select-Object -Property __server,DisplayName,startname |
Export-Csv c:\temp\Get-ServiceAccountInfo.csv -Append
} Catch {
$computer.Name | Out-File c:\temp\Get-ServiceAccountInfoerrorlog.txt -Append
}
}