• No results found

Running commands

4.1 Not scripting, but running commands

4.5.2 Parameter name aliases

Parameters can also have their own aliases, although they can be terribly difficult to find, as they aren’t displayed in the help files or anyplace else convenient. For exam- ple, the Get-EventLog command has a -computerName parameter. To discover its aliases, you’d run this command:

PS C:\> (get-command get-eventlog | select -ExpandProperty parameters).comp

utername.aliases

We’ve boldfaced the command and parameter names; replace these with whatever command and parameter you’re curious about. In this case, the output reveals that -Cn is an alias for -ComputerName, so you could run this:

PS C:\> Get-EventLog -LogName Security -Cn SERVER2 -Newest 10

Tab completion will show you the -Cn alias; if you typed Get-EventLog -C and started pressing Tab, it’d show up. But the help for the command doesn’t display -Cn at all, and Tab completion doesn’t indicate that -Cn and -ComputerName are the same thing. 4.5.3 Positional parameters

When you’re looking at a command’s syntax in its help file, you can spot positional parameters easily:

SYNTAX

Get-ChildItem [[-Path] <String[]>] [[-Filter] <String>] [-Exclude <String[]>] [-Force [<SwitchParameter>]] [-Include <String[]>] [-Name [<SwitchParameter>]] [-Recurse [<SwitchParameter>]] [-UseTransaction [<SwitchParameter>]] [<CommonParameters>]

Here, both -Path and -Filter are positional, and we know that because the parame- ter name is contained within square brackets. A clearer explanation is available in the full help (help Get-ChildItem -full, in this case), which looks like this:

-Path <String[]>

Specifies a path to one or more locations. Wildcards are permitted. The default location is the current directory (.). Required? false

Position? 1

Default value Current directory

Accept pipeline input? true (ByValue, ByPropertyName) Accept wildcard characters? True

That’s a clear indication that the -Path parameter is in position 1. For positional parameters, you don’t have to type the parameter name—you can provide its value in the correct position. For example,

PS C:\> Get-ChildItem c:\users Directory: C:\users

Mode LastWriteTime Length Name ---- --- --- ---- d---- 3/27/2012 11:20 AM donjones d-r-- 2/18/2012 2:06 AM Public

That’s the same as this:

PS C:\> Get-ChildItem -path c:\users Directory: C:\users

Mode LastWriteTime Length Name ---- --- --- ---- d---- 3/27/2012 11:20 AM donjones d-r-- 2/18/2012 2:06 AM Public

The problem with positional parameters is that you’re taking on the responsibility of remembering what goes where. You must type all positional parameters first, in the correct order, before you can add any named (non-positional) parameters. If you get the parameter order mixed up, the command fails. For simple commands like Dir, which you’ve probably used for years, typing -Path feels weird and almost nobody does it. But for more complex commands, which might have three or four positional parameters in a row, it can be tough to remember what goes where.

For example, this is a bit difficult to read and interpret:

PS C:\> move file.txt users\donjones\

This version, which uses parameter names, is easier to follow:

PS C:\> move -Path c:\file.txt -Destination \users\donjones\

This version, which puts the parameters in a different order, is allowed when you use the parameter names:

PS C:\> move -Destination \users\donjones\ -Path c:\file.txt

We tend to recommend against using positional (that is, unnamed) parameters unless you’re banging out something quick and dirty at the command line. In anything that will persist, like a batch file or a blog post, include all of the parameter names. We try to do that as much as possible in this book, except in a few instances where we have to shorten the command line to make it fit within the printed pages.

4.6

Cheating, a bit: Show-Command

Despite our long experience using PowerShell, the complexity of the commands’ syn- tax can sometimes drive us nuts. One cool new feature of PowerShell v3 is the Show-Command cmdlet. If you’re having trouble getting a command’s syntax right, with all the spaces, dashes, commas, quotes, and whatnot, Show-Command is your friend. It

lets you specify the command name you’re struggling with and then graphically prompts you for the command’s parameters. As shown in figure 4.2, each parameter set (which you learned about in the previous chapter) is on a separate tab, so there’s no chance of mixing and matching parameters across sets—pick a tab and stick with it. When you’re done, you can either click Run to run the command or—and we like this option better—click Copy to put the completed command on the clipboard. Back in the shell, paste the command (right-click in the console, or Ctrl-V in the ISE) to look at it. This is a great way to teach yourself the proper syntax, as shown in figure 4.3, and you’ll get the proper syntax every time.

Figure 4.2 Show-Command uses a graphical prompt to complete command parameters.

Figure 4.3 Show-Command produces the proper command-line syntax based on your entries in its dialog box.

When you produce a command this way, you’ll always get the full-form command: full command name, full parameter names, all parameter names typed (that is, nothing entered positionally), and so on. It’s a great way to see the perfect, preferred, best- practice way of using PowerShell.

Unfortunately, Show-Command only works with single commands. When you start stringing together multiple commands, it can only help you with one at a time.

4.7

Support for external commands

So far, all of the commands you’ve run in the shell (at least, the ones we’ve suggested that you run) have been built-in cmdlets. Almost 400 of those cmdlets come built into the latest version of the Windows client operating system, thousands into the server operating system, and you can add more—products like Exchange Server, SharePoint Server, and SQL Server all come with add-ins that each includes hundreds of addi- tional cmdlets.

But you’re not limited to the cmdlets that come with PowerShell—you can also use the same external command-line utilities that you have probably been using for years, including Ping, Nslookup, Ipconfig, Net, and so forth. Because these aren’t native PowerShell cmdlets, you use them the same way that you always have. PowerShell will launch Cmd.exe behind the scenes, because it knows how to run those external com- mands, and any results will be displayed within the PowerShell window. Go ahead and try a few old favorites right now. We’re often asked how you can use PowerShell to map a regular network drive—one that can be seen from within Explorer. We always use Net Use, and it works fine within PowerShell.

TRY IT NOW Try running some external command-line utilities that you’ve used previously. Do they work the same? Do any of them fail?

The Net Use example illustrates an important lesson: with PowerShell, Microsoft (per- haps for the first time ever) isn’t saying, “you have to start over and learn everything all over again.” Instead, Microsoft is saying, “if you already know how to do something, keep doing it that way. We’ll try to provide you with better and more complete tools going forward, but what you already know will still work.” One reason there’s no “Map-Drive” command within PowerShell is that Net Use already does a good job, so why not keep using it?

NOTE We’ve been using that Net Use example for years – ever since Power- Shell v1 first came out. It’s still a good story – but PowerShell v3 proves that Microsoft is starting to find the time to create PowerShell-ish ways to do those old tasks. In v3, you’ll find that the New-PSDrive command now has a -Persist parameter, which – when used with the FileSystem provider – cre- ates drives that are visible in Explorer.

There are certainly instances where Microsoft has provided better tools than some of the existing, older ones. For example, the native Test-Connection cmdlet provides more options and more flexible output than the old, external Ping command. But if

you know how to use Ping, and it’s solving whatever need you have, go right on using it. It’ll work fine from within PowerShell.

All that said, we do have to deliver a harsh truth: not every single external com- mand will work flawlessly from within PowerShell, at least not without a little tweaking on your part. That’s because PowerShell’s parser—the bit of the shell that reads what you’ve typed and tries to figure out what you want the shell to do—doesn’t always guess correctly. Sometimes you’ll type an external command and PowerShell will mess up, start spitting out errors, and generally not work.

For example, things can get tricky when an external command has a lot of parame- ters—that’s where you’ll see PowerShell break the most. We’re not going to dive into the details of why it works, but here’s a way to run a command that will ensure its parameters work properly:

$exe = "C:\Vmware\vcbMounter.exe" $host = "server" $user = "joe" $password = "password" $machine = "somepc" $location = "somelocation" $backupType = "incremental"

& $exe -h $host -u $user -p $password -s "name:$machine" -r $location -t $backupType

This supposes that you have an external command named vcbMounter.exe (which is a real-life command-line utility supplied with some of VMWare’s virtualization prod- ucts; if you’ve never used it or don’t have it, that’s fine—most old-school command- line utilities work the same way, so this is still a good teaching example). It accepts several parameters:

 -h for the host name

 -u for the user name

 -p for the password

 -s for the server name

 -r for a location

 -t for a backup type

What we’ve done is put all the various elements—the executable path and name, as well as all of the parameter values—into placeholders, which start with the $ charac- ter. That forces PowerShell to treat those values as single units, rather than trying to parse them to see if any of them contain commands or special characters or anything. Then we used the invocation operator (&), passing it the executable name, all of the parameters, and the parameters’ values. That pattern will work for almost any command-line utility that’s being grumpy about running within PowerShell.

Sound complicated? Well, here’s some good news: in PowerShell v3, you don’t have to mess around quite so much. Just add two dashes in front of any external com- mand. When you do so, PowerShell won’t even try to parse the command, it’ll just

pass it out to Cmd.exe. That means you can essentially run anything, using the exact syntax you would in Cmd.exe, and not worry about explaining it to PowerShell!

4.8

Dealing with errors

It’s inevitable that you’ll see some ugly red text as you start working with PowerShell; and probably from time to time even after you’re an expert-level shell user. Happens to us all. But don’t let the red text stress you out (personally, it takes us back to high school English class and poorly written essays, so “stress” is putting it mildly).

The alarming red text aside, PowerShell’s error messages are intended to be help- ful. For example, as shown in figure 4.4, they try to show you exactly where PowerShell ran into trouble.

Error messages almost always include the line and char (character) number where PowerShell got confused. In figure 4.4, it’s line 1, char 1—right at the beginning. It’s saying, “You typed ‘get,’ and I have no idea what that means.” That’s because we typed the command name wrong: it’s supposed to be Get-Command, not Get Command. Oops. What about figure 4.5?

The error message in figure 4.5, “Second path fragment must not be a drive or

UNC name,” is confusing. What second path? We didn’t type a second path. We typed one path, c:\windows, and a command-line parameter, /s. Right?

Well, no. One of the easiest ways to solve this kind of problem is to read the help, and to type the command out completely. If we’d typed Get-ChildItem -path C:\Windows, we’d have realized that /s isn’t the correct syntax. We meant -recurse. Sometimes, the error message might not seem helpful—and if it seems like you and PowerShell are speaking different languages, you are. PowerShell obviously isn’t going to change its language, so you’re probably the one in the wrong, and consulting the help and spelling out the entire command, parameters and all, is often the quickest way to solve the problem. And don’t forget to use Show-Command to try and figure out the right syntax.

4.9

Common points of confusion

Whenever it seems appropriate, we’ll wrap up each chapter with a brief section that covers some of the common mistakes we see when we teach classes. The idea is to help you see what most often confuses other administrators like yourself, and to avoid those problems—or at least to be able to find a solution for them—as you start work- ing with the shell.