Chapters/handling-errors/snippets.ps1

# notice error behavior
Get-Service -Name BITS,Nobody,WinRM



# try each in turn
Get-Service -Name BITS,Nobody,WinRM -EA Continue
Get-Service -Name BITS,Nobody,WinRM -EA SilentlyContinue
Get-Service -Name BITS,Nobody,WinRM -EA Inquire
Get-Service -Name BITS,Nobody,WinRM -EA Stop



# moving from this...
        Write-Verbose "Connecting to $computer over $protocol"
        $session = New-CimSession -ComputerName $computer `
                                  -SessionOption $option


# to this...
        Write-Verbose "Connecting to $computer over $protocol"
        $params = @{'ComputerName'=$Computer
                    'SessionOption'=$option
                    'ErrorAction'='Stop'}
        $session = New-CimSession @params



# observe structure - will not execute as-is
 PROCESS {
    foreach ($computer in $computername) {
 
        if ($protocol -eq 'Dcom') {
            $option = New-CimSessionOption -Protocol Dcom
        } else {
            $option = New-CimSessionOption -Protocol Wsman
        }
 
        Try {
            Write-Verbose "Connecting to $computer over $protocol"
            $params = @{'ComputerName'=$Computer
                        'SessionOption'=$option
                        'ErrorAction'='Stop'}
            $session = New-CimSession @params
  
            Write-Verbose "Querying from $computer"
            $os_params = @{'ClassName'='Win32_OperatingSystem'
                           'CimSession'=$session}
            $os = Get-CimInstance @os_params

            $cs_params = @{'ClassName'='Win32_ComputerSystem'
                           'CimSession'=$session}
            $cs = Get-CimInstance @cs_params

            $sysdrive = $os.SystemDrive
            $drive_params = @{'ClassName'='Win32_LogicalDisk'
                              'Filter'="DeviceId='$sysdrive'"
                              'CimSession'=$session}
            $drive = Get-CimInstance @drive_params

            $proc_params = @{'ClassName'='Win32_Processor'
                             'CimSession'=$session}
            $proc = Get-CimInstance @proc_params |
                    Select-Object -first 1

  
            Write-Verbose "Closing session to $computer"
            $session | Remove-CimSession
  
            Write-Verbose "Outputting for $computer"
            $obj = [pscustomobject]@{'ComputerName'=$computer
                       'OSVersion'=$os.version
                       'SPVersion'=$os.servicepackmajorversion
                       'OSBuild'=$os.buildnumber
                       'Manufacturer'=$cs.manufacturer
                       'Model'=$cs.model
                       'Procs'=$cs.numberofprocessors
                       'Cores'=$cs.numberoflogicalprocessors
                       'RAM'=($cs.totalphysicalmemory / 1GB)
                       'Arch'=$proc.addresswidth
                       'SysDriveFreeSpace'=$drive.freespace}
            Write-Output $obj
        } Catch {

        } #try/catch
 
    } #foreach
} #PROCESS



# observe catch behavior - will not execute as-is
        } Catch {
            Write-Warning "FAILED $computer on $protocol"
            
            # Did we specify protocol fallback?
            # If so, try again. If we specified logging,
            # we won't log a problem here - we'll let
            # the logging occur if this fallback also
            # fails
            If ($ProtocolFallback) {
                If ($Protocol -eq 'Dcom') {
                    $newprotocol = 'Wsman'
                } else {
                    $newprotocol = 'Dcom'
                } #if protocol

                Write-Verbose "Trying again with $newprotocol"
                $params = @{'ComputerName'=$Computer
                            'Protocol'=$newprotocol
                            'ProtocolFallback'=$False}
                
                If ($PSBoundParameters.ContainsKey('LogFailuresToPath')){
                    $params += @{'LogFailuresToPath'=$LogFailuresToPath}
                } #if logging

                Get-MachineInfo @params
            } #if protocolfallback

            # if we didn't specify fallback, but we
            # did specify logging, then log the error,
            # because we won't be trying again
            If (-not $ProtocolFallback -and
                $PSBoundParameters.ContainsKey('LogFailuresToPath')){
                Write-Verbose "Logging to $LogFailuresToPath"
                $computer | Out-File $LogFailuresToPath -Append
            } # if write to log

        } #try/catch




# pseudo-code
Try {
    $ErrorActionPreference = "Stop"
    # run something that doesn't have -ErrorAction
    $ErrorActionPreference = "Continue"
} Catch {
    # ...
}



# pseudo-code
Try {
    # something here generates an exception
} Catch [Exception.Type.One] {
    # deal with that exception here
} Catch [Exception.Type.Two] {
    # deal with the other exception here
} Catch {
    # deal with anything else here
} Finally {
    # run something else
}