Windows Running Windows PowerShell Scripts Against Multiple Computers
-
Upload
lylienkiet -
Category
Documents
-
view
213 -
download
0
Transcript of Windows Running Windows PowerShell Scripts Against Multiple Computers
Windows PowerShell Tip of the Week17 out of 20 rated this helpful
Here’s a quick tip on working with Windows PowerShell. These are published every week for as long as we can
come up with new tips. If you have a tip you’d like us to share or a question about how to do something, let us
know.
Find more tips in the Windows PowerShell Tip of the Week archive.
Running Windows PowerShell Scripts Against Multiple Computers
If there’s a problem with the Script Center – wait a minute, who said there was a problem with the Script
Center? Boy, if we ever get our hands on that guy we’ll ….
Um, as we were saying, if there’s a problem with the Script Center it’s the fact that our scripts are almost all
designed to be run against one computer at a time. That was actually done on purpose: because we are an
educational site, we try to keep our scripts as simple as we can. Our concern is that, if we start to randomly
toss in the code required to get a script to run against multiple machines, we run the risk of needlessly
complicating and confusing matters. Therefore, we tend to keep our scripts short and sweet.
Yes, just like the Scripting Guys.
Of course, in real life things aren’t so simple; system administrators (that is, people who actually use scripts, as
opposed to simply writing about them) need to manage multiple machines. As you might expect then, rarely
does a day go by that the Scripting Guys don’t get at least one email that begins, “I really like your script that
does X. But how can I get that script to run against multiple computers?”
In response to those questions, we posted our Remote/Multiple Computer Templates, templates that
VBScript users can use as the foundation for a VBScript script that runs against multiple computers. That’s nice,
but how do those templates help Windows PowerShell users?
Well, to be honest, they don’t. (Although we’ll see if we can create some similar templates for Windows
PowerShell users.) But don’t despair, PowerShell users; we haven’t forgotten about you. In fact, this week – and
next – we’ll show you different ways to get a script to run against multiple computers. This week we’ll show you
how to supply multiple computer names as command-line arguments; how to read computer names from a
text file; and, as a bonus, how to repeatedly prompt a user to enter a computer name. Next week – well, who
knows what we’ll do next week? But you can bet we’ll have such tasks as reading computer names from an
Excel spreadsheet and running a script against all the computers in an OU.
But first things first.
Top of page
Using Command-Line Arguments
Let’s take a look at one of the “classic” ways to run a script against multiple computers: by supplying computer
names as command-line arguments. For example, suppose we have a simple WMI script that retrieves BIOS
information from a computer (or computers). In that case, we might start the script using a command similar to
this:
That’s pretty cool, isn’t it? Except for one thing: how do we grab those command-line arguments and use them
within the script?
Well, here’s one way to do that:
You’re right: this is remarkably simple, isn’t it? By default, any command-line arguments supplied to a Windows
PowerShell script are automatically placed into a special variable named $args. That means that the moment
we run our sample command $args will be equal to this:
atl-fs-01
atl-fs-02
That was pretty easy. After all, we didn’t even have to do anything; like we said, our command-line arguments
were automatically tucked away into $args for us. That’s good. Now here’s something even better: to access,
and make us of, those arguments, all we need to do is set up a very basic foreach loop, one that cycles
through each item in the $args collection:
As you can see, we’re simply looping through the $args collection, using $i as our loop variable. (Note that the
loop conditions are enclosed in parentheses.) And then, inside curly braces, we call the Get-WMIObject
cmdlet, passing two parameters:
Win32_BIOS, the name of the WMI class we want to retrieve information from.
The –computername parameter, followed by the name of the computer we want to run the script
bios.ps1 atl-fs-01 atl-fs-02
foreach ($i in $args)
{Get-WMIObject Win32_BIOS -computername $i}
foreach ($i in $args)
against. In this case, the name of the computer is represented by the loop variable $i.
What’s that going to give us? That’s going to give us output similar to this:
Not bad, except for one problem; how are we supposed to know which computer is which?
Good question. But, again, don’t despair; here’s one way to fix that. Just change the script block so that it looks
like this:
All we’ve done here is add a couple of things to our foreach script block. Before we call Get-WMIObject we’re
echoing back:
The name of the computer (stored in the loop variable $i).
A carriage return-linefeed (stored in the “escape sequence” `n).
A series of equals signs.
In turn, that gives us output that looks like this:
SMBIOSBIOSVersion : 68DTT Ver. F.0F
Manufacturer : Hewlett-Packard
Name : EPP runtime BIOS - Version 1.1
SerialNumber :
Version : HP - 15060620
SMBIOSBIOSVersion : 70DTT Ver. E.0A
Manufacturer : Hewlett-Packard
Name : EPP runtime BIOS - Version 1.2
SerialNumber :
Version : HP - 16060624
{$i + "n" + "=========================="; Get-WMIObject Win32_BIOS -computername $i}
atl-fs-01
==========================
SMBIOSBIOSVersion : 68DTT Ver. F.0F
Manufacturer : Hewlett-Packard
Name : EPP runtime BIOS - Version 1.1
This time around, even a Scripting Guy can tell which BIOS information belongs to which computer.
And yes, PowerShell being PowerShell, we could have created a single string rather than concatenating three
separating strings. In other words, we could have done this:
We just thought that the concatenation might be a little easier for people to understand.
Top of page
Reading Computer Names From a Text File
OK, so what about reading in computer names from a text file? For example, suppose you have a text file
(C:\Scripts\Test.txt) that looks like this:
How do we get a script to run against each of the computers listed in this text file? Why, like this, of course:
SerialNumber :
Version : HP - 15060620
atl-fs-02
==========================
SMBIOSBIOSVersion : 70DTT Ver. E.0A
Manufacturer : Hewlett-Packard
Name : EPP runtime BIOS - Version 1.2
SerialNumber :
Version : HP - 16060624
{"$in=========================="; Get-WMIObject Win32_BIOS -computername $i}
atl-fs-01
atl-fs-02
atl-fs-03
atl-fs-04
atl-fs-05
$a = Get-Content "C:\Scripts\Test.txt"
foreach ($i in $a)
{$i + "n" + "=========================="; Get-WMIObject Win32_BIOS -computername $i}
Again, there’s not much to this script. In line 1, we simply use the Get-Content cmdlet to read the contents of
the text file and store that information in a variable named $a. When Get-Content stores information in a
variable, that information is stored as an array, with each line in the text file becoming a separate item in the
array. And because each line in our text file just happens to be the name of a computer, we now have an array
($a) containing the name of each computer we want to run the script against.
The rest is very similar to the first script we showed you. We set up a foreach loop that, in this case, loops
through the values in the array $a. And what do we do with each of those values? The same thing we did in the
first script: we use the Get-WMIObject to retrieve information about the BIOS installed on that computer.
It’s that simple. As an extra special bonus, this is also how you could hardcode computer names in the script
and then run that script against all those computers. Remember how, in line 1, we created an array by reading
in lines from a text file? Well, alternatively, we could manually create that array. In that case, our script would
look like this:
You know, this is almost too easy.
Note. Don’t worry; we said “almost.”
Incidentally, for you diehard Windows PowerShell users, those users who like to employ the minimum number
of keystrokes, this modified version of the script will do the same thing:
The only difference here is that instead of using the Get-Content cmdlet to read in the contents and store that
information in a variable, we’re simply placing the Get-Content command directly in the foreach loop.
And yes, Windows PowerShell allows you to do things like that. Pretty slick, huh?
$a = "atl-fs-01", "atl-fs-02", "atl-fs-03", "atl-fs-04", "atl-fs-05"
foreach ($i in $a)
{$i + "n" + "=========================="; Get-WMIObject Win32_BIOS -computername $i}
foreach ($i in Get-Content "C:\Scripts\Test.txt")
{$i + "n" + "=========================="; get-wmiobject win32_bios -computername $i}
Did you find this helpful?
Top of page
Prompting the User to Enter a Computer Name
Let’s do one more before we call it a day. Here’s a script that repeatedly prompts the user to enter a computer
name. After the user enters the name and presses ENTER, the script uses Get-WMIObject to retrieve BIOS
information for that machine. It then prompts the user to enter the name of another computer; this continues
until the user presses ENTER without entering a computer name.
Here’s what the script looks like:
As you can see, we start off by setting up a do while loop that runs as long as (while) the variable $a is not
equal to (-ne) an empty string. Inside the loop, we start off by calling the Read-Host cmdlet, displaying the
message “Please enter a computer name” and storing the user input in the variable $a. Read-Host prompts a
user for input, then sits patiently until the user finishes typing and presses ENTER.
From there we set up an if statement that checks the value of $a. As long as $a is not an empty string, the
script will retrieve the BIOS information from the computer whose name was just entered. Once that’s done we
swing back to the top of the loop and repeat the process, asking the user to enter another computer name.
That’s all we have time for this week. See you next week for yet another exciting Windows PowerShell tip.
Top of page
© 2014 Microsoft. All rights reserved.
do
{
$a = Read-Host "Please enter the computer name"
if ($a -ne "")
{$a + "n" + "=========================="; Get-WMIObject Win32_BIOS -computername $a}
}
while ($a -ne "")
Yes No