2

I am trying to test if a DNS zone exists in Powershell using the following cmdlet:

Get-DNSServerZone abc.com

That works great, but what I need to do now is turn that into a True/False evaluation depending on if there was an error or if there was data returned.

For example, this is a TRUE scenario:

$a = Get-DnsServerZone abc.com
$a

ZoneName                            ZoneType        IsAutoCreated   IsDsIntegrated  IsReverseLookupZone  IsSigned
--------                            --------        -------------   --------------  -------------------  --------
abc.com                            Secondary       False           False           False

Whereas this is a FALSE scenario:

$a = Get-DnsServerZone def.com
Get-DnsServerZone : The zone def.com was not found on server DNSSERVER1.
At line:1 char:6
+ $a = Get-DnsServerZone def.com
+      ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (def.com:root/Microsoft/...S_DnsServerZone) [Get-DnsServerZone], CimException
+ FullyQualifiedErrorId : WIN32 9601,Get-DnsServerZone

What I'm struggling with is how to evaluate on that? In layman's terms I need to check if $a has actual data or not.

Many thanks!

Dominic Brunetti
  • 989
  • 3
  • 18
  • 36

2 Answers2

4

what I need to do now is turn that into a True/False evaluation depending on if there was an error or if there was data returned.

If you can simply ignore failures and don't need the object returned by Get-DNSServerZone, you can do the following:

$zoneExist = [bool] (Get-DNSServerZone abc.com -ErrorAction Ignore)
  • -ErrorAction Ignore quietly ignores any (non-terminating) errors.

    • Passing Ignore to the common -ErrorAction parameter) simply discards the error, whereas SilentlyContinue, while also not outputting an error, still records it in the automatic $Error collection, allowing later inspection.

    • You could also complement -ErrorAction SilentlyContinue with something like
      -ErrorVariable err, which would additionally record the command-specific errors in self-chosen variable $err, via the common -ErrorVariable parameter.

  • Cast [bool] maps Get-DNSServerZone's output to $true (an object describing the zone was output) or $false (nothing was output (to the success output stream), because an error occurred), taking advantage of PowerShell's implicit to-Boolean conversion.

If you want the zone-description object too:

$zoneExist = [bool] ($zoneInfo = Get-DNSServerZone abc.com -ErrorAction Ignore)

An alternative is to capture the zone-information first, and to query the automatic $? variable afterwards, which contains a Boolean value ($true or $false) that indicates whether the most recently executed statement caused any errors (whether suppressed or not).

$zoneInfo = Get-DNSServerZone abc.com -ErrorAction Ignore
$zoneExist = $?
mklement0
  • 382,024
  • 64
  • 607
  • 775
  • 1
    Thank you very much! This was extremely helpful in understanding error handling in PS. I had no idea you could query `$?` like that! – Dominic Brunetti Dec 17 '20 at 21:26
  • 1
    Glad to hear it was helpful, @DominicBrunetti; my pleasure. One more tip: only _terminating_ errors can be caught with `try` / `catch`, but you can promote non-terminating errors to terminating ones with `-ErrorAction Stop`, as in Theo's answer. For a comprehensive overview of PowerShell's surprisingly complex error handling, see [this GitHub docs issue](https://github.com/PowerShell/PowerShell-Docs/issues/1583). – mklement0 Dec 17 '20 at 21:30
3

You could wrap it in a try..catch:

try {
    Get-DNSServerZone abc.com -ErrorAction Stop
}
catch {
    Write-Warning "zone abc.com doesn't exist"
}

Or go the other way and ignore errors:

$a = Get-DNSServerZone abc.com -ErrorAction SilentlyContinue
if (!$a) {
    Write-Warning "abc.com doesn't exist"
}
Theo
  • 57,719
  • 8
  • 24
  • 41