Adding error capturing to script

This topic contains 6 replies, has 3 voices, and was last updated by Profile photo of Alex Aymonier Alex Aymonier 2 years, 4 months ago.

  • Author
    Posts
  • #17839
    Profile photo of Alex Aymonier
    Alex Aymonier
    Participant

    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

  • #17840
    Profile photo of Adnan Rashid
    Adnan Rashid
    Participant

    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  
     
    
     
  • #17841
    Profile photo of Adnan Rashid
    Adnan Rashid
    Participant

    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  
     
    
     
     
  • #17843
    Profile photo of Don Jones
    Don Jones
    Keymaster

    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.

  • #17853
    Profile photo of Adnan Rashid
    Adnan Rashid
    Participant

    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.

  • #17879
    Profile photo of Alex Aymonier
    Alex Aymonier
    Participant

    Thanks guys. This gives me stuff to work with, i'll let you know how i get on.

    Alex

  • #17938
    Profile photo of Alex Aymonier
    Alex Aymonier
    Participant

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

You must be logged in to reply to this topic.