Summary: Microsoft Scripting Guy, Ed Wilson, shows how to get a directory listing from remote servers by using Windows PowerShell and how to write results to an CSV file.

Microsoft Scripting Guy, Ed Wilson, is here. It is here: Windows PowerShell Saturday #003 in Atlanta, Georgia (Alpharetta). The speaker’s dinner last night was great, and it gave the Scripting Wife a chance to meet new friends and to renew acquaintances with people we rarely get to see. Overall, it was great for everyone except me as I am still at home with no voice to speak of and a stuffy head.Today, more than 100 people will gather and spend the day listening to world-class speakers talking about Windows PowerShell. It will be fun.

Getting a directory listing from a group of servers

The other day, a follower of @ScriptingGuys on Twitter asked me about getting a directory listing from a bunch of servers (like over a hundred) and writing the results to an Excel Spreadsheet. There are three tasks here.

  1. Obtain a listing of the servers to query.
  2. Obtain the directory listing from the servers.
  3. Write results to an Excel spreadsheet.

Obtain a listing of servers to query

There are numerous ways to obtain a listing of servers. The different methodologies appear here.

  1. Read a Text file (or a CSV file) containing a list of all the servers.
  2. Read a SQL Server database (or an Excel spreadsheet) containing a list of all the servers.
  3. Use ADO to query Active Directory to obtain a list of all the servers.
  4. Use the [ADSISearcher] type accelerator to query Active Directory and obtain a list of all the servers.
  5. Use a Windows PowerShell cmdlet to query Active Directory.

I have talked about all of these technologies in previous years. You can use the search function or the blog tags to find these articles. Actually, each of the approaches has advantages and disadvantages. Reading a text file is very simple, but then, so is using a Windows PowerShell cmdlet to query Active Directory. The problem with a text file is that you have to always have access to it, and you also have to maintain it. With Active Directory, it will always be up to date, and maintenance is not, in fact, an issue. Most of the time, nowadays, I tend to query Active Directory. It is fast, easy, and accurate. The easiest way to get a computer listing is to use the Get-ADComputer cmdlet from the AD DS Windows PowerShell tools. For my Windows 8 laptop, I downloaded them from this link. Keep in mind that the RSAT tools are both operating system-specific as well as processor-specific.

Note   I have written a number of articles that deal with the RSAT tools for Windows 7. I have not yet written about the RSAT tools for Windows 8.

The first thing I do is import the ActiveDirectory module. I use the command appearing here (ipmo is the alias for Import-Module, and *active* is a wild card pattern that finds the ActiveDirectory module).

ipmo *active*

Note   In Windows PowerShell 3.0, you do not need to import a module prior to using it, but if I know that I am going to use a module, I go ahead and import it, because it is faster.

Next, I use the Get-ADComputer cmdlet and use a filter that returns everything. I store the results in a $cn variable. This command appears here.

$cn = Get-ADComputer -Filter *

Obtaining the directory listings

Now, I create a credential object to permit me to run a remote command on the remote servers. To do this, I use the Get-Credential cmdlet as shown here.

$cred = Get-Credential -Credential iammred\administrator

Note   The account I am using does not have admin rights on the remote computers, but it does have permission to query Active Directory. If your account does not have rights to query Active Directory, you would need to use the credentials earlier when you query Active Directory. The command would be something like this: Get-ADComputer -Filter * -Credential $cred

Once I have a credential object, I need to use the Invoke-Command cmdlet to run the command on the remote servers. This command appears here (icm is an alias for the Invoke-Command cmdlet).

icm -Credential $cred -Cn $cn.name -ScriptBlock {dir}

Note   This command takes advantage of Windows PowerShell 3.0 automatic enumeration of collections that permit me to access a single property from a collection of objects. If you are not using Windows PowerShell 3.0, you will need to do something like this: $a = $cn | foreach {$_.name}

Write to a CSV file

To write to a CSV file, I use the Export-CSV cmdlet and specify a local path. Because I am not using a shared storage mechanism, but rather using a CSV file on my local system, I add the Export-CSV command after the Invoke-Command cmdlet and use a local path. The command appears here.

| export-csv -path c:\fso\serverDir.csv –Append

Putting it all together

The complete sequence of commands is shown here.

ipmo *active*

$cn = Get-ADComputer -Filter *

$cred = Get-Credential -Credential iammred\administrator

icm -Credential $cred -Cn $cn.name -ScriptBlock {dir} | export-csv -path c:\fso\serverDir.csv –Append

Four commands. That is it. Now, I did not do any error checking, and, as a result, I got a bunch of errors in the Windows PowerShell console when I ran the command. This was due to servers being offline on my home network. Here are the errors.

Image of command output

When I double-click on the CSV file, it opens automatically in Microsoft Excel. This is shown here.

Image of Excel output

One thing to notice is that I did not make any changes to the output. If I am not interested in all this information, I can use the Select-Object cmdlet to choose what to write to the CSV file.

Note   I have written quite a bit about working with CSV files from within Windows PowerShell.

That should get you started collecting directory inventories from your servers. Have a great weekend, and I will see you tomorrow.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy