-
Microsoft PowerShell and Nested Try/Catch
On a recent project, I learned something new about PowerShell’s Try/Catch. You can nest another Try/Catch in the Catch of the first Try/Catch. When I showed this to my PowerShell mentor, he said he didn’t know that could be done. I figured I might as well make a quick post about it.
I was using some code from Jeremy Saunders to gather CPU information on a XenApp 6.5 farm. the Get-XAServer cmdlet has a property to store the FQDN of a XenApp server but it is not populated. This XenApp farm contained servers in two different forests and two different domains. All my scripts I wrote for the project using the XenApp cmdlets and Get-EventLog stuff worked with no issues. Using Get-WmiObject broke because that cmdlet will not work for computers not in the same forest.
I did a Get-Help Get-WmiObject and noticed a -Authority parameter.
1234Get-WmiObject [-Authority <string>] [-Amended] [-AsJob] [-Authentication {Default | None | Connect | Call | Packet
| PacketIntegrity | PacketPrivacy | Unchanged}] [-ComputerName <string[]>] [-Credential <PSCredential>] [-EnableAll
Privileges] [-Impersonation {Default | Anonymous | Identify | Impersonate | Delegate}] [-Locale <string>] [-Namespa
ce <string>] [-ThrottleLimit <int>] [<CommonParameters>]
The explanation for that parameter:
12345-Authority <string>
Specifies the authority to use to authenticate the WMI connection. You can specify standard NTLM or Kerberos au
thentication. To use NTLM, set the authority setting to ntlmdomain:<DomainName>, where <DomainName> identifies
a valid NTLM domain name. To use Kerberos, specify kerberos:<DomainName>\<ServerName>". You cannot include the
authority setting when you connect to the local computer.
I wondered if I could use -Authority ntlmdomain:<DomainName> if the first Get-WmiObject failed.
Jeremy’s code wraps the call to Get-WmiObject in a Try {} Catch {}. So I thought it would be worth testing to see if I could do:
1234567891011121314try
{
}
catch
{
try
{
}
catch
{
}
}
Sure enough it worked (and surprised me).
Here are the basics of Jeremy’s code.
123456789101112131415161718192021222324252627282930add-pssnapin
"citrix.xenapp.commands"
$names
=
Get-XAServer
-ea
0 | Select ServerName | Sort ServerName
foreach
(
$name
in
$names
)
{
write-host
"$($name.servername)"
Try
{
$ComputerInformation
=
Get-WmiObject
-Class
Win32_ComputerSystem
-computername
$Name
.servername
-ErrorAction
Stop
$Processors
=
Get-WmiObject
-Class
win32_Processor
-computername
$Name
.servername
-ErrorAction
Stop
$Disks
=
Get-WmiObject
-Class
win32_LogicalDisk
-computername
$Name
.servername
-ErrorAction
Stop
}
Catch
{
Try
{
$ComputerInformation
=
Get-WmiObject
-Authority
ntlmdomain:domain2
-Class
Win32_ComputerSystem
-computername
$Name
.servername
-ErrorAction
Stop
$Processors
=
Get-WmiObject
-Authority
ntlmdomain:domain2
-Class
win32_Processor
-computername
$Name
.servername
-ErrorAction
Stop
$Disks
=
Get-WmiObject
-Authority
ntlmdomain:domain2
-Class
win32_LogicalDisk
-computername
$Name
.servername
-ErrorAction
Stop
}
Catch
{
$ErrorDescription
=
"Error connecting using the Get-WmiObject cmdlet."
$Host
.UI.WriteErrorLine(
"*ERROR*: - $ErrorDescription"
)
}
}
}
None of this would have been necessary if Citrix had populated the ServerFqdn property. If they had, I could have just stripped the domain part off and just used one call to Get-WmiObject.
Hey, learn something new every day in this field.
Thanks
Webster
April 15, 2016
PowerShell