Expert Solutions: Advanced Event 1 of the 2010 Scripting Games

Bookmark and Share

 

(Note: These solutions were written for Advanced Event 1 of the 2010 Scripting Games.)

 

Advanced Event 1 (Windows PowerShell)

Image of Kirk MunroKirk Munro, the world’s first self-proclaimed Poshoholic, is a Microsoft MVP and Windows PowerShell Solutions Architect who has worked in the IT industry for more than 13 years. He has spent the majority of that time working with IT administrators, creating and developing software solutions to facilitate systems management. At Quest Software, Kirk works on Windows PowerShell solutions, most notably PowerGUI, where he is responsible for the architecture of new PowerGUI features and the management and development of the PowerPacks used to extend the PowerGUI administrative console.

 

·         Bloghttp://poshoholic.com

·         Twitterhttps://twitter.com/Poshoholic

·         MVP Profilehttp://tinyurl.com/Poshoholic

·         MVP Canada Profile: http://blogs.technet.com/canitpro/archive/2008/04/03/mvp-profile-kirk-munro.aspx

·         LinkedIn Profilehttp://www.linkedin.com/in/kirkmunro


————


 Module:
http://gallery.technet.microsoft.com/ScriptCenter/en-us/b4bbc1e3-426c-47c1-954c-4ba36d598584

Manifest: http://gallery.technet.microsoft.com/ScriptCenter/en-us/0034cd8b-1a01-4e50-922e-74bbdac14657

 


This event is very typical of what you might encounter in the real world. Your boss wants you to “check computers on the network” (whatever that means) and log a timestamp in the registry when the check has completed. If you were handed a task like this, you might think you can’t really take action on it because it raises more questions than answers. What you might not realize, though, is that you can create a Windows PowerShell script for this that solves this task even though you didn’t get a lot of details from your boss.


The first thing I did when I was writing this task was fire up the PowerGUI Script Editor (my Windows PowerShell editor of choice), and use the PowerShell v2 snippets to create a module. The “function (module, public, advanced)” snippet sets up my function framework in one empty file and the “module manifest” snippet sets up the module manifest in another empty file. I called my function Invoke-NetworkCheck, and then I saved the two files as AdvancedEvent1.psm1 and AdvancedEvent1.psd1, respectively, in an AdvancedEvent1 folder in my personal Modules folder (My DocumentsWindowsPowerShellModules). After this was in place, I was able to update the function with the functionality I needed and the documentation describing it and the manifest with the version and other settings, leaving me with a module that I can send to my boss so that he can try it out.


For the functionality in the module, there are a few design decisions I made up front when planning out my function, as follows:

  • I decided to accept computer names as values from the pipeline. Accepting computer names this way allowed me to let users get computer names from wherever they want rather than be limited to computer names in a text file (of course, they can get them from a file too using Get-Content if they want to).

  • Anything that I didn’t know up front from my boss’s request translated into function parameters with default values. This included the registry path, the registry value name, and the network check itself.  Taking this approach allowed me to create a versatile function that could do any network check and write the timestamp in any registry location.

  • Being a good network citizen, I added a Credential parameter so that you don’t have to be in “god mode” to get the function to work.

  • The function internals are pretty straightforward. In the begin block, I create a hashtable with the optional Credential parameter so that I can use splatting when I am calling Test-Connection and Invoke-Command in the process block of the function (a good technique to use when dealing with optional credentials). In the process block, I ping each computer first with Test-Connection and if it responds, I invoke the network check with Invoke-Command. After all computers have been processed, I write the current timestamp to the registry in the end block.


The complete Invoke-NetworkCheck function definition is shown here:

 


function Invoke-NetworkCheck {

      <#

      .SYNOPSIS

      Runs a network check on local and remote computers.

 

.DESCRIPTION

The Invoke-NetworkCheck command runs a network check on local and remote computers and returns all output from the commands, including errors. The default network check is a lookup of the Windows PowerShell version; however, this may be replaced with any script block. With a single Invoke-NetworkCheck command, you can run the network check on multiple computers.

When the network check has finished running, the current date and time will be written to the registry in the location identified by RegistryPath and RegistryValue.

To run a single network check on a remote computer, use the ComputerName parameter.

You can also use Invoke-NetworkCheck on a local computer to evaluate the network check on the local machine. Windows PowerShell converts the script block to a command and runs the command immediately in the current scope.

Before using Invoke-NetworkCheck to run commands on a remote computer, read about_Remote.

.PARAMETER  ScriptBlock

Specifies the network check to run. Enclose the network check script in curly braces ( { } ) to create a script block. This parameter is required.

Any variables in the network check are evaluated on the remote computer.

.PARAMETER  RegistryPath

Specifies a path to the Registry key where a timestamp will be written when the network check task has finished. The timestamp will only be written once after all computers have been checked. The value of RegistryPath is used exactly as it is typed. No characters are interpreted as wildcards.

.PARAMETER  RegistryValue

Specifies the name of the registry value where a timestamp will be written after the network check task has finished. The timestamp will only be written once after all computers have been checked. The value of RegistryValue is used exactly as it is typed. No characters are interpreted as wild card characters.

.PARAMETER Credential

Specifies a user account that has permission to perform this action. The default is the current user.

 

    Type a user name, such as “Poshoholic” or “PoshStudiosPoshoholic”, or enter a variable that contains a PSCredential object, such as one generated by the Get-Credential cmdlet. When you type a user name, you will be prompted for a password.

.PARAMETER ComputerName

Specifies the computers on which the command runs. The default is the local computer.

    When you use the ComputerName parameter, Windows PowerShell creates a temporary connection that is used only to run the specified command and is then closed.

    Type the NETBIOS name, IP address, or fully-qualified domain name of one or more computers in a comma-separated list. To specify the local computer, type the computer name, “localhost”, or a dot (.).

    To use an IP address in the value of the ComputerName parameter, the command must include the Credential parameter. Also, the computer must be configured for HTTPS transport or the IP address of the remote computer must be included in the WinRM TrustedHosts list on the local computer. For instructions for adding a computer name to the TrustedHosts list, see “How to Add a Computer to the Trusted Host List” in about_Remote_Troubleshooting.

      Note:  On Windows Vista and later versions of Windows, to include the local computer in the value of the ComputerName parameter, you must open Windows PowerShell with the “Run as administrator” option.

 

.EXAMPLE

      PS C:> Invoke-NetworkCheck

 

Major  Minor  Build  Revision PSComputerName

—–  —–  —–  ——– ————–

6      1      7600   16385    localhost

 

Description

———–

This command invokes the default network check on the local computer.

The default network check is to look up the Windows PowerShell version. The script runs on the local computer through a remote connection and the results are returned with the computer name added in the PSComputerName property.

On Windows Vista and later versions of Windows, you must open Windows PowerShell with the “Run as administrator” option in order for the Invoke-NetworkCheck command to work against the local computer.

 

.EXAMPLE

      PS C:> Get-Content C:Computers.txt | Invoke-NetworkCheck

 

Major  Minor  Build  Revision PSComputerName

—–  —–  —–  ——– ————–

6      1      7600   16385    dc

6      1      7600   16385    exchange

 

Description

———–

This command invokes the default network check on the computers identified in the computers.txt file.

The default network check is to look up the Windows PowerShell version. The script runs on each computer through a remote connection and the results are returned with the computer name added in the PSComputerName property.

The results of this command are returned in the order in which the scripts finish running on the remote computers, which may not be the same order as the computers that are listed in C:Computers.txt.

.EXAMPLE

      PS C:> Get-Content C:Computers.txt | Invoke-NetworkCheck -ScriptBlock {Get-Service wuauserv} -Verbose

      VERBOSE: Invoking network check on ‘dc’.

 

      Status   Name               DisplayName                            PSComputerName

      ——   —-               ———–                            ————–

      Stopped  wuauserv           Windows Update                         dc

      VERBOSE: Invoking network check on ‘exchange’.

      Running  wuauserv           Windows Update                         exchange

      VERBOSE: Network Check Completed: 03/28/2010 21:55:15