{"id":321,"date":"2021-04-02T05:00:37","date_gmt":"2021-04-02T12:00:37","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/powershell-community\/?p=321"},"modified":"2021-04-02T07:46:12","modified_gmt":"2021-04-02T14:46:12","slug":"testing-the-connection-to-computers-in-the-active-directory","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell-community\/testing-the-connection-to-computers-in-the-active-directory\/","title":{"rendered":"Testing the connection to computers in the Active Directory"},"content":{"rendered":"<p><strong>Q:<\/strong> As an administrator, I often have to do a lot of reporting on the servers in my domain. Is there a simple way to test the connection to every server in my domain or every server or client host in a specific OU?<\/p>\n<p><strong>A:<\/strong> Of course you can do this with PowerShell! You can use the Active Directory cmdlets and <code>Test-Connection<\/code>, although it is not as simple as one might like.<\/p>\n<h2>Using the <code>ActiveDirectory<\/code> module<\/h2>\n<p>Microsoft has developed several modules to help you deploy and manage AD in your organisation or via Azure. The <code>ActiveDirectory<\/code> module is one which Microsoft ships with Windows Server (although not installed by default). You can also load the Remote Server Administration (RSAT) module for AD on a Windows 10 host. The RSAT module allows you to manage the AD using PowerShell from a remote machine. For more details on the <code>ActiveDirectory<\/code> module, see the <a href=\"https:\/\/docs.microsoft.com\/powershell\/module\/addsadministration\/\">ActiveDirectory<\/a> module documentation.<\/p>\n<p>Use the <code>Get-ADComputer<\/code> account to return details about some or all computers within the AD. There are several ways to use <code>Get-ADComputer<\/code> to get just the computer accounts you want with any property you need. These include using the <strong>Identity<\/strong> and <strong>Filter<\/strong> parameters.<br \/>\nEvery computer account returned by <code>Get-ADComputer<\/code> contains two important properties: <strong>Name<\/strong> and <strong>DNSHostName<\/strong>. The <strong>Name<\/strong> property is the single-label name of the computer (aka the NetBIOS name). The <strong>DNSHostName<\/strong> property is the fully qualified DNS name for the computer. Like this:<\/p>\n<pre><code class=\"powershell-console\">PS&gt; Get-ADComputer -Filter * | Format-Table -Property Name, DNSHostName\n\nName         DNSHostName\n----         -----------\nCOOKHAM1     Cookham1.cookham.net\nwin10lt      Win10LT.cookham.net\ncookham24    cookham24.cookham.net\nSLTPC        sltpc.cookham.net\nCOOKHAM4LTDC Cookham4LTDC.cookham.net\n<\/code><\/pre>\n<p>So you might be tempted to think it simple to test connections to each computer. You pipe the output of <code>Get-ADComputer<\/code> to <code>Test-Connection<\/code>, and it just works. Sadly, it&#8217;s not quite so simple.<\/p>\n<p>If you try this, here is what you would see:<\/p>\n<pre><code class=\"powershell-console\">PS&gt; Get-ADComputer -Filter * | Test-Connection\nTest-Connection: Cannot validate argument on parameter 'TargetName'. The argument is null, empty, or an element of the argument collection contains a null value. Supply a collection that does not contain any null values and then try the command again.\nTest-Connection: Cannot validate argument on parameter 'TargetName'. The argument is null, empty, or an element of the argument collection contains a null value. Supply a collection that does not contain any null values and then try the command again.\nTest-Connection: Cannot validate argument on parameter 'TargetName'. The argument is null, empty, or an element of the argument collection contains a null value. Supply a collection that does not contain any null values and then try the command again.\nTest-Connection: Cannot validate argument on parameter 'TargetName'. The argument is null, empty, or an element of the argument collection contains a null value. Supply a collection that does not contain any null values and then try the command again.\nTest-Connection: Cannot validate argument on parameter 'TargetName'. The argument is null, empty, or an element of the argument collection contains a null value. Supply a collection that does not contain any null values and then try the command again.\n<\/code><\/pre>\n<p>What is going on here?<\/p>\n<h2>Property\/Parameter misalignment<\/h2>\n<p>What we have here is a classic, albeit relatively uncommon, situation. The <code>Test-Connection<\/code> cmdlet uses the parameter name <strong>Target<\/strong> to indicate the computer to which you are testing a connection. However, in this pipelined command, the objects produced by <code>Get-ADComputer<\/code> do not contain properties of that name. Instead, these objects have properties named <strong>Name<\/strong> and <strong>DNSHostName<\/strong>.<\/p>\n<p><div class=\"alert alert-primary\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Note<\/strong><\/p>With Windows PowerShell, you used the parameter <strong>ComputerName<\/strong> to indicate the computer you are investigating. With PowerShell 7, the developers have changed this parameter name to <strong>TargetName<\/strong>. For best compatibility, the cmdlet defines the**<code>ComputerName** alias to this parameter.\nThis cmdlet lets you use either **TargetName** or **Computername** with<\/code>Test-Connection`.<\/div><\/p>\n<h2>ForEach-Object to the rescue<\/h2>\n<p>It is pretty easy to get around this parameter\/property alignment challenge. You use the <code>Foreach-Object<\/code> cmdlet, like this:<\/p>\n<pre><code class=\"powershell-console\">PS&gt; Get-ADComputer -Filter * | \n             ForEach-Object {\"$_\";Test-Connection -TargetName $_.Name;\"\"}\n\nCN=COOKHAM1,OU=Domain Controllers,DC=cookham,DC=net\n   Destination: COOKHAM1\nPing Source      Address      Latency BufferSize Status\n                                 (ms)        (B)\n---- ------      -------      ------- ---------- ------\n   1 cookham24   10.10.10.9         0         32 Success\n   2 cookham24   10.10.10.9         0         32 Success\n   3 cookham24   10.10.10.9         0         32 Success\n   4 cookham24   10.10.10.9         0         32 Success\n\nCN=win10lt,OU=CookhamHQ,DC=cookham,DC=net\n   Destination: win10lt\nPing Source      Address          Latency BufferSize Status\n                                     (ms)        (B)\n---- ------      -------          ------- ---------- ------\n   1 cookham24   *                      0         32 DestinationHost\u2026\n   2 cookham24   *                      0         32 DestinationHost\u2026\n   3 cookham24   *                      0         32 DestinationHost\u2026\n   4 cookham24   *                      0         32 DestinationHost\u2026\n\nCN=SLTPC,CN=Computers,DC=cookham,DC=net\n   Destination: SLTPC\nPing Source      Address                   Latency BufferSize Status\n                                              (ms)        (B)\n|---- ------      -------                   ------- ---------- ------\n   1 cookham24   2a02:8010:6386:0:f810:2b\u2026       1         32 Success\n   2 cookham24   2a02:8010:6386:0:f810:2b\u2026       0         32 Success\n   3 cookham24   2a02:8010:6386:0:f810:2b\u2026       0         32 Success\n   4 cookham24   2a02:8010:6386:0:f810:2b\u2026       3         32 Success\netc\n<\/code><\/pre>\n<h2>Using the Extensible Type System<\/h2>\n<p>If you plan to do a lot of this sort of work, there is a more straightforward way to get around this property\/parameter alignment issue. You can use the Extensible Type System (ETS) to extend any AD Computer object to contain an alias to the <code>Name<\/code> or <code>DNSHostName<\/code> property. You define this extension via a small XML file which you then import, like this:<\/p>\n<pre><code class=\"powershell-console\">PS&gt; Get-Content '.aaatypes.types.ps1xml'\n&lt;Types&gt;\n &lt;Type&gt;\n    &lt;Name&gt;Microsoft.ActiveDirectory.Management.ADComputer&lt;\/Name&gt;\n    &lt;Members&gt;\n       &lt;AliasProperty&gt;\n          &lt;Name&gt;TargetName&lt;\/Name&gt;\n          &lt;ReferencedMemberName&gt;DNSHostName&lt;\/ReferencedMemberName&gt;\n         &lt;\/AliasProperty&gt;\n    &lt;\/Members&gt;\n  &lt;\/Type&gt;\n\n&lt;\/Types&gt;\n\nPS&gt; Update-TypeData -PrependPath .aaatypes.types.ps1xml\nPS&gt; Get-ADComputer -Identity Cookham1 | Test-Connection\n\n   Destination: Cookham1.cookham.net\n\nPing Source           Address                   Latency BufferSize Status\n                                                   (ms)        (B)\n---- ------           -------                   ------- ---------- ------\n   1 cookham24        10.10.10.9                      0         32 Success\n   2 cookham24        10.10.10.9                      0         32 Success\n   3 cookham24        10.10.10.9                      0         32 Success\n   4 cookham24        10.10.10.9                      0         32 Success\n<\/code><\/pre>\n<p>You can persist this ETS extension by adding the <code>Update-TypeData<\/code> to your PowerShell profile. That way, every time you start a PowerShell session, that ETS extension is in place and ready to assist you.<\/p>\n<p>For details of and background to the ETS, see the <a href=\"https:\/\/docs.microsoft.com\/powershell\/scripting\/developer\/ets\/overview\">Extended Type System Overview<\/a>.<\/p>\n<h2>Summary<\/h2>\n<p>The <code>Get-ADComputer<\/code> cmdlet produces objects whose properties the object developers have not aligned, pipeline wise, with <code>Test-Connection<\/code>. There is a simple way around that, using <code>For-EachObject<\/code>, although it takes a bit more typing. You can also use the ETS to extend the <strong>ADComputer<\/strong> object to have a more friendly alias.<\/p>\n<h2>Tip of the Hat<\/h2>\n<p>This article was based on a request in this blog&#8217;s issue queue See the post <a href=\"https:\/\/github.com\/PowerShell\/Community-Blog\/issues\/21\">Request &#8211; How to get all the alive servers in the domain?<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Q: As an administrator, I often have to do a lot of reporting on the servers in my domain. Is there a simple way to test the connection to every server in my domain or every server or client host in a specific OU? A: Of course you can do this with PowerShell! You can [&hellip;]<\/p>\n","protected":false},"author":4034,"featured_media":77,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[13],"tags":[22,23],"class_list":["post-321","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell","tag-active-directory","tag-networking"],"acf":[],"blog_post_summary":"<p>Q: As an administrator, I often have to do a lot of reporting on the servers in my domain. Is there a simple way to test the connection to every server in my domain or every server or client host in a specific OU? A: Of course you can do this with PowerShell! You can [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/posts\/321","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/users\/4034"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/comments?post=321"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/posts\/321\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/media\/77"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/media?parent=321"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/categories?post=321"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/tags?post=321"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}