Published onWindows DevCenter(http://www.windowsdevcenter.com/)
http://www.windowsdevcenter.com/pub/a/windows/2006/11/07/top-10-tips-for-using-windows-powershell.html
See thisif you're having trouble printing code examples
Top 10 Tips for Using Windows PowerShell
byJeff Cogswell11/07/2006
PowerShell is Microsoft's newest replacement for the command line. It's still in beta, andthe latest version is available free for download here. For us older folks, we've had to deal with DOS in the past, and then we've held on to the CMD.exe program, which is pretty much the same as a DOS command prompt running under Windows. PowerShell is not an updated version of DOS. Rather, it's a complete command-line system that is far more powerful than any command-line prompt Microsoft has given us before. Starting to learn it, unfortunately, can be a bit overwhelming at first. After you've installed it and explored it a bit, the following tips will help make your life much easier.
1. Remember the consistencies
Remember that commands have a verb-noun format and parameter names start with a -. You can use either / or \ in paths.
Probably the most basic, fundamental rule in using PowerShell is that the commands all have a common format. When you remember the format, you can more easily remember the commands.
The format is verb-noun. For example:
Set-DateWrite-DebugGet-ItemGet-WmiObject
Each of these is a verb followed by a hyphen followed by a noun. Further, the noun is singular, even if it seems like it should be plural. Thus:
Get-Process
returns all the running processes.
But the consistency goes beyond just the names. Parameters are consistent. In the worlds of DOS and Unix, commands either use - or / to denote a parameter name. In PowerShell, all parameter names start with -.
However, path names, on the other hand, can be separated by either a forward slash or a backward slash. You can use either, whichever you're most comfortable with. If you need to combine paths, however, you can easily use the built-in command join-path like so:
join-path c:\ \temp
which results in c:\temp. (This is handy because you don't have to manually remove the extra slashes that might result in just combining the two strings.)
2. Remember the useful commands
UseGet-Command
to get a list of commands andGet-Help
to find out help on the commands. You can also pass-?
as a parameter to a command to obtain help. UseTabExpansion
(and, optionally, find aTabExpansion
replacement).
Whenever you're using a new language, you want to know the vocabulary. The second release candidate of PowerShell contains 129 commands. That's a lot to learn and memorize. But you'll want to be at least familiar with what's available, and you'll want to make sure you know some of the more common ones. To see all the commands type
Get-Command
One command isGet-Help
. You can use this to find out help on a particular command:
Get-Help Get-Member
will display help on the commandGet-Member
. Or you can pass-?
as a parameter like so:
Get-Member -?
The built-in commands also provide different levels of help. The default help provides basic information. You can get more help providing details on the parameters along with examples by adding-detailed
to theGet-Help
command:
Get-Help Get-Member -detailed
And you can get even more help by typing-full
:
Get-Help Get-Member -full
Since many commands are long and we, as computer people, usually don't want to type huge commands, PowerShell includes an alias feature along with several built-in aliases. You can list all the aliases like so:
PS C:\WINDOWS\system32> Get-AliasCommandType Name Definition----------- ---- ----------Alias ac Add-ContentAlias asnp Add-PSSnapinAlias clc Clear-ContentAlias cli Clear-ItemAlias clp Clear-ItemProperty...
The Tab key has a special usage that helps you find commands. If you remember the verb, you can type the verb then the hyphen, and press Tab repeatedly to cycle through the different possible commands starting with that verb. If you type:
Get-
and then start pressing Tab, you'll seeGet-Acl
, thenGet-Alias
, thenGet-AuthenticodeSignature
, and so on.
However, the built-in tab expansion feature isn't that sophisticated, and Microsoft knows it. That's why it made a function called TabExpansion that can be modified. Search the web for PowerShell TabExpansion (no space in the second word) and see what's out there. People have written TabExpansion replacements and there are some pretty good ones out there. Find one that suits your needs. (Incidentally, you can see the source for the TabExpansion function usingGet-Content function:TabExpansion
.)
Here's a list of some of the commands I find myself using often. When you use commands, you'll probably want to know any available aliases as well.
Command Aliases
Command | Aliases |
---|---|
Copy-Item | cpi, cp, copy |
ForEach-Object | foreach, % |
Get-ChildItem | dir, ls |
Get-Command | gcm |
Get-Content | cat, type |
Get-Content | gc, type, cat |
Get-Help | help |
Get-Location | gl, pwd |
Move-Item | mi, mv, move |
Remove-Item | ri, rd, del, rm, rmdir |
Rename-Item | rni, ren |
Set-Location | cd, chdir |
Where-Object | where |
Get-Command
takes some parameters to help you find the commands you need. For example, if you're looking for commands that have the word Format in them, you can type:
Get-Command *Format*
However, you might only want the commands that start with the verb Format (such asFormat-Table
). This will work:
Get-Command -verb Format
That will return the commands whose verb is exactly Format. If you type
Get-Command -verb Form
you will not get back those with the verb Format unless you use a wildcard pattern:
Get-Command -verb Form*
You can similarly specify the noun:
Get-Command -noun Alias
will list all commands dealing with aliases.
There's also a couple handy single-character aliases.%
is an alias forForEach-Object
and?
is an alias forWhere-Object
.
3. Learn the fundamental types and built-in variables
Learn the fundamental types and how the parser recognizes them. Master regular expressions so your life will be complete.
The PowerShell scripting language includes several basic types that are useful in your work. And, you can create variables of these types. You have at your disposal all the built-in types in .NET. This includes, for example, strings, numbers, arrays, and dictionaries (which some people know as hashes or maps). The types are all built around the .NET types. (I talk about .NET in the next section.)
The command parser will decide the types based on what you type. For example, if you type
5
you will be specifying an integer. Variable names get a$
before them, and you can store the integer like so:
PS C:\> $a = 5PS C:\> $a5PS C:\>
You can determine the built-in .NET type by callingGetType()
:
PS C:\> $a.GetType()IsPublic IsSerial Name BaseType-------- -------- ---- --------True True Int32 System.ValueType
The parser also recognizes other basic types. Doubles can be created with a decimal point:
PS C:\> $b = 3.1415926PS C:\> $b3.1415926PS C:\> $b.GetType().NameDouble
Like many of today's scripting languages, you can use either single or double quotes for strings, whichever is convenient for the problem at hand. For example, if you need double-quotes in the string, you can use single quotes for the string itself:
$c = '<span style="border:1px solid none">'
To create an array, just provide a list of comma-separated items:
PS C:\> $d = 1,2,3,"Hello"PS C:\> $d123HelloPS C:\> $d.GetType()IsPublic IsSerial Name BaseType-------- -------- ---- --------True True Object[] System.Array
If necessary, you can put parentheses around the array. This is useful for arrays of arrays:
$e = (1,2,3,(4,5,6))
You can specify ranges of integers using the .. operator like so:
$f = 1..5
will create an array containing 1,2,3,4,5.
To create a dictionary, use the@
symbol like so:
PS C:\> $myhash = @{ 'one'=1; 'two'=2; 'three'=3 }PS C:\> $myhashName Value---- -----two 2three 3one 1PS C:\> $myhash['one']1PS C:\> $myhash['four']PS C:\>
Since .NET includes powerful regular expression capabilities, PowerShell includes a regex type. Just put the wordregex
in brackets ([]) before a string to create a regular expression. Then you can use the regular expression with the -match operators. Here's an example:
PS C:\> $re = [regex]"abc[123]"PS C:\> "abc1" -match $reTruePS C:\> "abc4" -match $reFalsePS C:\>
If you're not familiar with regular expressions, then now is a great time to learn them. The more you know regular expressions, the easier time you'll have with PowerShell as well as many programming languages. Go to your favorite search engine and type in "learn regular expressions". There are several good pages out there. But probably the best source is the O'Reilly bookMastering Regular Expressionsby Jeffrey Friedl. This is one of the few books that should be required reading for every computer professional.
The shell includes some built-in variables that you can use, too. Here are some of them:
- $$: Last token of previous line
- $?: Last success/fail status
- $^: First token of previous line
$pshome: The installation directory of PowerShell. This is useful if you're going to modify some of the configuration files, such as types.ps1xml, like so:
scite (join-path $pshome types.ps1xml)
(Sciteis the free text editor I use.)
If you want to use a specific type without relying on the parse, PowerShell comes with several built-in type shortcuts. A type shortcut is a shortened form of a type name. The Microsoft PowerShell's blog includes anentry listing some of them.
Learning and understanding the types can be unwieldy, however, especially if a command returns an object of a type you're not familiar with. If you're savvy with reading online helps,this blog entryis a way to enhance your PowerShell so you can access the online help for any object's type.
(If you make this change, you'll have to re-sign your file. See the tip "Customize your environment" for more information.) When you implement this modification, you can find the online help for any object's type. The technique isn't perfect and doesn't work for every object, but it does work most of the time.
4. Know your .NET
The .NET framework is the foundation on which PowerShell runs. The more you know about .NET, the better your PowerShell experience will be.
To get the most out of PowerShell, you should be familiar with the .NET framework. The framework's help is available online in its entirety at. Scroll down to the System heading. This is where you'll find the basic types such as Int32, String, and Array.
Remember, the framework is simply a huge collection of classes and types that you can use in your PowerShell work. The more you know of these types, the better off you are. If you look up entries on your types, you'll know what you can do with objects. For example, if you click the page for System, scroll down and click String, you'll get the entry for the String class.
Most of the commands return an object (or a set of objects) that are, in fact, .NET objects. For example, theGet-Date
command on the surface may appear to just print out the current date and time. But in fact, it returns an object of typeDateTime
, which is part of the .NET framework. Similarly, if you typeGet-ChildItem
(or an alias,dir
), you see a directory listing, but in fact, are looking at a list of objects, each of which is either aDirectoryInfo
or aFileInfo
object. These are .NET classes.
The .NET framework is organized into a huge hierarchy, with all classes being derived fromObject
. TheObject
class provides some base functionality common to every single class in .NET. One base functionality is a function calledToString
. This function returns a text representation of an object. The way this pertains to PowerShell is that given any object, you can always get a string representation of it. (In fact, this is exactly how PowerShell prints out an object to the console.)
5. Understand the pipeline is object-based not text-based
Remember that objects are passed through the pipeline, not just text, which means a great deal of information is available to you at any point in the pipe.
If you've worked with other shells such as cmd in Windows or any of the Unix-based shells, you know that commands can output text, which can in turn be passed (piped) to other commands. For example, in cmd and DOS, thedir
command prints out a list of files. This list is in the form of text. If you just run thedir
command, you'll see the list appear in the console window. However, you can instead send that text as input into another command; this is called piping. The more command, for example, reads in text and writes out only a page worth, and then waits for a keypress before writing another page worth of text:
C:\WINDOWS >dir /ad | more Volume in drive C has no label. Volume Serial Number is BCFB-2313 Directory of C:\WINDOWS11/04/2006 10:59 PM <DIR> .11/04/2006 10:59 PM <DIR> ..06/07/2004 07:03 PM <DIR> $NtUninstallKB824105$06/07/2004 07:05 PM <DIR> $NtUninstallKB824141$10/15/2004 09:06 PM <DIR> $NtUninstallKB824151$06/07/2004 07:01 PM <DIR> $NtUninstallKB825119$06/07/2004 07:00 PM <DIR> $NtUninstallKB828035$06/07/2004 06:58 PM <DIR> $NtUninstallKB828741$06/07/2004 06:59 PM <DIR> $NtUninstallKB833407$-- More --
Over the years, people have taken the fact that this pipe is text and written some really powerful utilities to manipulate the text. Years ago, awk and grep arrived, which let you process the text. (awk, for example, could easily take the preceding text and break up the lines into records divided by spaces. grep lets you search through the text for patterns; people still use grep a lot.) Today we have even more powerful languages for text processing, such as Perl.
While simple commands in DOS such asdir
use text, more powerful tools work with objects. If you're managing a set of processes on a Windows system, a single process is not just a line of text. A single process is an object made up of more objects such as the ID for the process, the security settings, and so on. These are more than just text.
If a tool retrieves a set of processes and then writes the information out just as text for another tool to use, the second tool is getting cheated. The tool is only getting a text-based form of the processes, not the actual objects.
A better approach, then, is to simply let the first tool pipe the actual objects on to the second tool. At first this might seem like a problem since ultimately we are dealing with a console window which displays text. But if you think about thedir | more
commands working together, the only output that finally makes it to the console window is the output from the more. The information passed fromdir
tomore
is never displayed on the console.
Of course, eventually the objects do have to be displayed as text in the console window. That's where theToString
method comes in that I mentioned in the previous section. At the end of the pipeline the console can simply callToString
to get a text-representation of the object, and write that text to the console window.
Here's an example:
PS C:\WINDOWS> dir | sort LastWriteTime | more Directory: Microsoft.PowerShell.Core\FileSystem::C:\WINDOWSMode LastWriteTime Length Name---- ------------- ------ -----a--- 7/4/1995 1:33 PM 11776 Ckrfresh.exe-a--- 7/31/1995 5:44 PM 212480 PCDLIB32.DLL-a--- 5/3/1996 10:36 AM 18432 Setup_ck.dll-ar-- 5/3/1996 12:21 PM 27648 Setup_ck.exe-a--- 7/22/1998 12:29 AM 21 CS_SETUP.ini-a--- 10/29/1998 3:45 PM 306688 IsUninst.exe-a--- 1/12/1999 10:39 AM 6656 delttsul.exe-a--- 1/12/1999 10:40 AM 29184 rmud.exe-a--- 6/18/1999 4:49 PM 165888 Ckconfig.exe-a--- 11/10/1999 3:05 PM 86016 unvise32qt.exe...
(dir
is an alias forGet-Children
, sort is an alias forSort-Object
, and more is a function that callsOut-Host -paging
. Thus,dir | sort LastWriteTime | more
is shorthand forGet-ChildItem | Sort-Object LastWriteTime | Out-Host -Paging
.)
This example lists the directory contents, sorts it on theLastWriteTime
field, and then writes it out per page. But since the objects pass through the pipeline and are only converted to text at the end, you can save the results of any output into a variable, preserving the types, like so:
PS C:\WINDOWS> $a = dir | sort LastWriteTime
The variable$a
now contains the results of the Sort-Object command, but the contents of$a
is not text. The data is preserved. Thedir
command (Get-ChildItem
) returned an array ofFileInfo
andDirectoryInfo
objects, which was piped through thesort
(Sort-Object
) command. Thus,$a
is an array ofFileInfo
andDirectoryInfo
objects. You can access the individual elements using brackets like so:
PS C:\WINDOWS> $a[0] Directory: Microsoft.PowerShell.Core\FileSystem::C:\WINDOWSMode LastWriteTime Length Name---- ------------- ------ -----a--- 7/4/1995 1:33 PM 11776 Ckrfresh.exePS C:\WINDOWS> $a[1] Directory: Microsoft.PowerShell.Core\FileSystem::C:\WINDOWSMode LastWriteTime Length Name---- ------------- ------ -----a--- 7/31/1995 5:44 PM 212480 PCDLIB32.DLL
In the next section I talk about calling methods on objects in more detail but here you can see that if you callGetType
on the objects you can see for sure the type of objects you have (and that they definitely aren't text strings). Here I find out the type of my$a
variable:
PS C:\WINDOWS> $a.GetType()IsPublic IsSerial Name BaseType-------- -------- ---- --------True True Object[] System.Array
The $a object is an array. Let's see what the first element is:
PS C:\WINDOWS> $a[0].GetType()IsPublic IsSerial Name BaseType-------- -------- ---- --------True True FileInfo System.IO.FileSystemInfo
6. Make use of the objects and their members
The objects that pass through the pipe are instances of classes. You can make use of their methods and data.
Don't forget that your objects, including those that are the results of the commands, have members that you can make use of. You can find an object's members using theGet-Member
command:
PS C:\Documents and Settings\Jeff> $a = "abc"PS C:\Documents and Settings\Jeff> Get-Member -InputObject $a TypeName: System.StringName MemberType Definition---- ---------- ----------Clone Method System.Object Clone()CompareTo Method System.Int32 CompareTo(Object value),...Contains Method System.Boolean Contains(String value)CopyTo Method System.Void CopyTo(Int32 sourceIndex,...EndsWith Method System.Boolean EndsWith(String value)......
If you pipe the output from one command throughGet-Member
,Get-Member
will list the members for each type of object that comes through. If two objects come through and they are of the same type,Get-Member
will only list the members once for that type. For example, if you want to know what members are available of the objects returned by theGet-Process
command, pipe the results throughGet-Member
, like so:
PS C:\Documents and Settings\Jeff> Get-Process | Get-Member TypeName: System.Diagnostics.ProcessName MemberType Definition---- ---------- ----------Handles AliasProperty Handles = HandlecountName AliasProperty Name = ProcessNameNPM AliasProperty NPM = NonpagedSystemMemorySizePM AliasProperty PM = PagedMemorySizeVM AliasProperty VM = VirtualMemorySizeWS AliasProperty WS = WorkingSetadd_Disposed Method System.Void add_Disposed(Event...add_ErrorDataReceived Method System.Void add_ErrorDataRecei......
TheWhere-Object
command can be used to filter objects in the pipeline, allowing only objects through that meet the criteria you specify. To specify criteria, you will access the members of the objects passing through the pipeline.
For example, although I didn't include the full output here, theGet-Process | Get-Member
results showed me the objects in the results ofGet-Process
each have a member calledVirtualMemorySize
. Suppose, then, I want to list all processes that have a virtual memory size greater than 100 MB (which is 104,857,600 bytes). Here's how I can do it:
PS C:\Documents and Settings\Jeff> Get-Process | Where-Object {$_.VirtualMemorySize -gt 104857600}Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName------- ------ ----- ----- ----- ------ -- ----------- 948 15 38928 52788 346 12.23 712 dexplore 256 10 72624 81592 194 136.00 2664 firefox 350 14 30948 44268 133 7.06 3576 OUTLOOK 309 8 31928 6404 833 221.14 356 sqlservr 334 9 22188 14784 817 0.53 852 sqlservr 1598 91 18668 27404 142 156.75 1864 svchost 356 24 15708 23740 169 201.47 1536 WINWORD
TheWhere-Object
command takes a parameter that is a script in curly braces. The script runs for each object passing through the pipeline. As each object passes through, it gets placed in the variable called$_
. Thus,$_.VirtualMemorySize
refers to theVirtualMemorySize
member of the object currently in the pipeline. The-gt
is the comparison operator for greater than; thus, I'm testing if the current object has a virtual memory size of greater than 104,857,600 bytes.
Get-ChildItem | foreach { $_.Fullname }
As you can see, you should be familiar with the members of the objects, which can be found in the online help. If you go to the online help page, scroll down and click on System, scroll down and click on String, you'll be at the help page for the String class. At the very bottom (as well as in the tree in the left pane) is an item called String Members. That page lists all the members for the String class.
For example, one member is EndsWith
. This tells you if a string ends with a given set of characters. You're free to use this member. Here's a quick example:
PS C:\> $a = "This is a test"PS C:\> $a.EndsWith("test")TruePS C:\> $a.EndsWith("this")FalsePS C:\>
7. Format your output
You have full control of how the format looks of your output using the variousFormat-
commands.
PowerShell shuttles objects through the pipeline and only obtains the text version of the objects when ready for display, unless told to do otherwise with the commands. If you look at the list of members in the objects that come out ofGet-Process
, however, you'll see far more than what you see in the output. Which members appear in the output? The answer comes from the system configuration. Inside the Windows PowerShell directory is a file calleddotnettypes.format.ps1xml. This is an XML file that describes the formatting to be used in the output of various types. There are actually several such files, each describing different types, each with the filename pattern*.format.ps1xml. Others includepowershellcore.format.ps1xmlandfilesystem.format.ps1xml. You can learn more about these fileshere.
To format the output, PowerShell users a command calledFormatTable
. This command takes a pipeline of objects and writes them out using the format defined as the*.format.ps1xml files.
You can, however, override the settings and choose which members appear in the output, like so:
Get-Process | Format-Table Id, Name Id Name -- ----2876 alg 532 ApntEx2044 Apoint3448 calc1824 CFSvcs2176 cmd3760 cmd1640 Crypserv1316 csrss
This will display the Id and Name columns in the table, regardless of the default settings.
PowerShell has four different Format commands:
Format-Custom
Format-List
Format-Table
Format-Wide
You can explore each of these withGet-Help
.
8. Remember everything is a hierarchy
PowerShell Drives exist for more than just the file system. You can access the registry, the environment, and other data as a drive.
The idea of a computer being arranged hierarchically has been around a long time. Unix has always treated all the hardware as being part of the hierarchical filesystem, for example. Similarly, PowerShell treats various aspects of the computer as drives. You can see what all drives are currently available with theGet-PSDrive
command:
PS C:\Documents and Settings\Jeff> Get-PSDriveName Provider Root CurrentLocation---- -------- ---- ---------------Alias AliasC FileSystem C:\ Documents and Settings\Jeffcert Certificate \D FileSystem D:\Env EnvironmentFunction FunctionHKCU Registry HKEY_CURRENT_USERHKLM Registry HKEY_LOCAL_MACHINEVariable Variable
The list of aliases, for example, is a drive. You can switch to that drive as you would any other drive like so:
PS C:\WINDOWS\system32> cd alias:PS Alias:\>PS Alias:\> dirCommandType Name Definition----------- ---- ----------Alias ac Add-ContentAlias asnp Add-PSSnapinAlias clc Clear-ContentAlias cli Clear-ItemAlias clp Clear-ItemPropertyAlias clv Clear-Variable
Thealias: drive
doesn't provide subdirectories. Others, however, such as theRegistry
, do:
PS Alias:\> cd HKCU:PS HKCU:\> dir Hive: Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USERSKC VC Name Property--- -- ---- -------- 2 0 AppEvents {} 1 0 CLSID {} 4 32 Console {ColorTable00, ColorTable01, ColorTab... 24 1 Control Panel {Opened} 0 8 Environment {BAKEFILE_PATHS, INCLUDE, LIB, PROMPT... 0 1 HBA {Version} 1 5 Identities {Identity Ordinal, Migrated5, Last Us... 3 0 Keyboard Layout {} 0 0 Movie Magic Screenwriter {} 19 0 Movie Magic Screenwriter Vo... {} 0 0 Network {} 1 1 Note-It {(default)} 4 1 Printers {DeviceOld} 1 1 RemoteAccess {InternetProfile} 1 7 S {AutodiscoveryFlags, DetectedInterfac...100 1 Software {(default)} 0 0 UNICODE Program Groups {} 2 0 Windows 3.1 Migration Status {} 1 0 Win_32 {} 0 1 SessionInformation {ProgramCount} 0 7 Volatile Environment {LOGONSERVER, CLIENTNAME, SESSIONNAME...PS HKCU:\> cd Software\MicrosoftPS HKCU:\Software\Microsoft> dir Hive: Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\MicrosoftSKC VC Name Property--- -- ---- -------- 1 0 Active Setup {} 3 0 ActiveMovie {} 2 0 Advanced INF Setup {} 1 0 ASF Stream Descriptor File {} 1 0 Automap {} 1 4 Broadband Networking {StatusTimeout, InternetStatusTimeout... 1 1 ClipArt Gallery {UserAdded} 0 5 Clipbook {WindowsClipBook Viewer, WindowsClipb... 0 2 Clock {iFormat, {CCF5A555-D92E-457b-9235-2B...
Just as you could in DOS, you can use filename patterns:
PS HKCU:\Software\Microsoft> dir *windows* Hive: Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\MicrosoftSKC VC Name Property--- -- ---- -------- 3 0 Windows {} 0 1 Windows Genuine Advantage {code} 0 5 Windows Help {Maximized, Xl, Xr, Yd...} 1 0 Windows Media {} 1 0 Windows NT {} 1 0 Windows Script {} 1 0 Windows Script Host {}
The?
character will match a single character. For example,abc?
will match all items starting withabc
followed by a single character. You can also use brackets to specify a set of characters to match. For example,abc[123]
will matchabc1
,abc2
, andabc3
.
9. Use flow controls and scripts
The PowerShell language is powerful and supports scripting.
Many commands take scripts as parameters. TheWhere-Object
command is one example. I showed you this code earlier:
Get-Process | Where-Object {$_.VirtualMemorySize -gt 104857600}
TheFor-Each
object can execute a script for each item in a list. Here's a simple example:
PS C:\WINDOWS\system32> 1..10 | foreach { $_ * 2 }2468101214161820
This isn't particularly useful by itself. But the technique is applicable in many places. For example, suppose you want to copy every text file in a directory that has the string#backup
in the first line to the c:\backups directory. Here's how you could do it:
dir *.txt | foreach { if ((Get-Content $_ -totalCount 1) -eq "#backup") { copy $_ c:\backups } }
This line starts withdir
(orGet-ChildItem
) and pipes the results through the foreach command. Theforeach
command runs the script shown in curly braces for each file encountered. The script reads the first line of each file (viaGet-Content
, passing-totalCount 1
to get only the first line), and compares it to the string#backup
. If the string matches, the script copies the file.
10. Customize your environment
You can customize your environment by saving functions and changes in theprofile.ps1files.
When you develop your own scripts to do the work you need, you'll probably want to save them for later. You might also want to create more aliases of the commands you find userful. For example, in the previous section I created a script that will back up text files that start with#backup
.
You can put your customizations in your own profile. The previous script would need to be a function such as this:
function Backup-TextFiles { dir *.txt | foreach { if ((Get-Content $_ -totalCount 1) -eq "#backup") { copy $_ c:\backups } } }
This function would then go in your profile. The profile is a file calledProfile.ps1, and it goes in your home directory, which is\Documents and Settings\<username>\My Documents\WindowsPowerShell\profile.ps1where<username>is replaced by your actual username.
However, before you can run the script, it must be signed for security. (Alternatively, you can turn off the security restrictions. Several blogs are saying to do this, but that's a really bad idea.) This is agreat linkthat explains how you can sign your script. (In the article, the author mentions adding a snap-in to MMC. To get there inmmc.exe, click File->Add/Remove Snap-in. Make sure when you run themakecert.exeutility, you're in the directory that the author mentions containsmakecert.exe. Also, I had to refresh the MMC window before my changes appeared.)
Conclusion
The new Windows PowerShell is big, but don't be overwhelmed by it. When I first started using it, I couldn't imagine how it could make my life easier. There were too many unfamiliar commands and the commands seemed very long to type. But in a short time, I started to learn the commands and aliases, and understand the whole way of thinking in the PowerShell world. I'm glad Microsoft has finally given us this tool and excited to see what new tools the community will build around PowerShell to help make our lives easier. Enjoy!
Jeff Cogswelllives near Cincinnati and has been working as a software engineer for over 15 years.
Return to theWindows DevCenter.
Copyright © 2006 O'Reilly Media, Inc.
//-->'Windows' 카테고리의 다른 글
Getting the network adaptor MAC address with WMI (0) | 2007.03.29 |
---|---|
Windows 시스템레벨 개발자에게 도움이 되는 사이트 (0) | 2006.11.10 |
DLL의 모든 것 (0) | 2006.11.10 |