Adding error capturing to script

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  
 

 
 

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 :slight_smile:

 

$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
    } 

}