PSMonday #12: Monday, July 18, 2016

Topic: PowerShell Remoting Continued

Notice: This post is a part of the PowerShell Monday series — a group of quick and easy to read mini lessons that briefly cover beginning and intermediate PowerShell topics. As a PowerShell enthusiast, this seemed like a beneficial way to ensure those around me at work were consistently learning new things about Windows PowerShell. At some point, I decided I would share these posts here, as well. Here’s the PowerShell Monday Table of Contents.

Last week was our initial discussion of PowerShell Remoting (PS Remoting). As it’s so necessary, I figured we’d keep with it for at least another week. Previously we used Invoke-Command to run a single command on a few remote computers. Let’s start today, by switching this around and sending a few commands, to a single, remote computer.

In this example, we start in section 1 (listed as <#1#>), by echoing the computer’s name, just as we did in last week’s PSMonday. In section 2, we assign the results of two mildly different commands to the $Folders and $FolderCount variables. $Folders will store the names of the directories on the current root drive, separated by commas. $FolderCount will store the number of directories on the current root drive. Once those variables are populated, we then echo their values, as part of two separate strings, in section 3.

Invoke-Command -ComputerName MEMSRV01 -ScriptBlock {
    <#1#>"**** $env:COMPUTERNAME ****"

    <#2#>$Folders = (Get-ChildItem -Path \ -Directory) -join ', '
    $FolderCount = (Get-ChildItem -Path \ -Directory).Count

    <#3#>"Root Drive Folders : $Folders"
    "Root Drive Folder Count : $FolderCount"
}

**** MEMSRV01 ****
Root Drive Folders : inetpub, PerfLogs, Program Files, Program Files (x86), support, Users, Windows
Root Drive Folder Count : 7

There is an option to assign the script block to a variable, and then use the variable as part of the Invoke-Command command. This might make the code a bit more readable. Here’s an example.

$ScriptBlock = {
    "**** $env:COMPUTERNAME ****"

    $Folders = (Get-ChildItem -Path \ -Directory) -join ', '
    $FolderCount = (Get-ChildItem -Path \ -Directory).Count

    "Root Drive Folders : $Folders"
    "Root Drive Folder Count : $FolderCount"
}

Invoke-Command -ComputerName MEMSRV01 -ScriptBlock $ScriptBlock

Either way you do it, these script blocks still have the potential to become rather lengthy. In this case, we might consider the -FilePath parameter. Instead of the -ScriptBlock parameter and a script block, Invoke-Command will read in the contents of a .ps1 file and run that against the remote computer.  Here’s the same code as above, that’s been saved as C:\ICMTestFile.ps1.

psmonday-12-monday-july-18-2016-01

With this file in place, we’ll rerun the previous commands using the -FilePath parameter and the path to the file as the parameter value.

Invoke-Command -ComputerName MEMSRV01 -FilePath C:\ICMTestFile.ps1

**** MEMSRV01 ****
Root Drive Folders : inetpub, PerfLogs, Program Files, Program Files (x86), support, Users, Windows
Root Drive Folder Count : 7

As you begin to use Invoke-Command and want to run more and more commands, keep this option in mind. Now, with that said, I think it’s important to know that I don’t personally see the -FilePath option used much. Consider why. When writing your own scripts and functions, or reading someone else’s, you’ll have to go outside of the script or function file to view what Invoke-Command is doing, and that could become tiresome, and difficult when troubleshooting.

Leave a Reply

Your email address will not be published.