Read Windows Server 2008 R2 Unleashed Online
Authors: Noel Morimoto
----
C:\
PS C:\>
To get information about a specified directory or file, you can use the Get-Item cmdlet:
PS C:\temp> get-item autorun.inf
Directory: C:\temp
742
CHAPTER 21
Automating Tasks Using PowerShell Scripting
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 8/7/2007 10:06 PM 63 autorun.inf
PS C:\temp>
To get information about directories or files under a specified directory, you can use the
Get-ChildItem cmdlet:
PS C:\> get-childitem c:\inetpub\wwwroot
Directory: C:\inetpub\wwwroot
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 10/4/2009 11:09 PM aspnet_client
-a--- 10/4/2009 2:10 PM 689 iisstart.htm
-a--- 10/4/2009 2:10 PM 184946 welcome.png
PS C:\>
ptg
Creating Directories or Files
Creating a directory or file in PowerShell is a simple process and just involves the use of
the New-Item cmdlet:
PS C:\> new-item -path c:\ -name work -type dir
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 10/7/2009 11:44 AM work
PS C:\>
In the preceding example, it should be noted that the itemtype parameter is a parameter
that must be defined. If this parameter is not defined, PowerShell prompts you for the
type of item to be created. An example of this is shown here:
PS C:\work> new-item -path c:\work -name script.log
Type: file
Directory: C:\work
Using Windows PowerShell
743
Mode LastWriteTime Length Name
---- ------------- ------ ----
21
-a--- 10/7/2009 8:58 PM 0 script.log
PS C:\work>
In the previous example, PowerShell prompts you to define the value for the itemtype
parameter. However, because you wanted to create a file, the value is defined as “file.”
NOTE
With files, in addition to using the New-Item cmdlet, you can use several other
cmdlets to create files. Examples of these are Add-Content, Set-Content, Out-Csv, and
Out-File. However, the main purpose of these cmdlets is for adding or appending con-
tent within a file.
Deleting Directories and Files
To delete directories and files in PowerShell, the Remote-Item cmdlet is used. Usage of this
cmdlet is shown in the next example:
PS C:\work> remove-item script.log
ptg
Notice how PowerShell doesn’t prompt you for any type of confirmation. Considering
that the deletion of an item is a very permanent action, you might want to use one of the
PowerShell common parameters to confirm the action before executing the command.
For example:
PS C:\work> remove-item test.txt -confirm
Confirm
Are you sure you want to perform this action?
Performing operation “Remove File” on Target “C:\work\test.txt”.
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help
(default is “Y”):
In the prior example, the confirm common parameter is used to verify the deletion of the
test.txt file. Usage of this parameter can help prevent you from making mistakes when
executing commands that might or might not be intended actions.
NOTE
In addition to the Remove-Item cmdlet, you can use the Clear-Content cmdlet to wipe
content from a file instead of deleting it.
744
CHAPTER 21
Automating Tasks Using PowerShell Scripting
Renaming Directories and Files
To rename directories and files in PowerShell, use the Rename-Item cmdlet:
PS C:\> rename-item c:\work scripts
When using the Rename-Item cmdlet, the argument for the first parameter named path is
defined as the path to the directory or file being renamed. The secondary parameter,
newName, is then defined as the new name for the directory or file.
Moving or Copying Directories and Files
To move and copy directories or files in PowerShell, you can use either the Move-Item or
Copy-Item cmdlets. An example of using the Move-Item cmdlet is as follows:
PS C:\> move-item -path c:\scripts -dest c:\work
PS C:\> get-childitem c:\work
Directory: C:\work
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 10/7/2009 9:20 PM scripts
ptg
PS C:\>
The syntax for using the Copy-Item cmdlet is very similar, as shown in the next example:
PS C:\work> copy-item 4444.log .\logs
PS C:\work> gci .\logs
Directory: C:\work\logs
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 10/7/2009 10:41 PM 6 4444.log
PS C:\work>
Reading Information from Files
To read information from a file, you can use the Get-Content cmdlet. An example of using
this cmdlet is as follows:
PS C:\work\logs> get-content 4444.log
PowerShell was here!
When the Get-Content cmdlet is executed, it reads content from the specified file line-by-
line and returns an object for each line that is read. For example:
Using Windows PowerShell
745
PS C:\work\logs> $logs = get-content 4444.log
PS C:\work\logs> $logs[0]
21
PowerShell was here!
PS C:\work\logs>
Managing the Registry
PowerShell has a built-in provider, Registry, for accessing and manipulating the Registry on
a local machine. The Registry hives available in this provider are HKEY_LOCAL_MACHINE
(HKLM) and HKEY_CURRENT_USER (HKCU). These hives are represented in a PowerShell
session as two additional PSDrive objects named HKLM: and HKCU:.
NOTE
The WshShell object has access to not only the HKLM: and HKCU: hives, but also
HKEY_CLASSES_ROOT (HKCR), HKEY_USERS, and HKEY_CURRENT_CONFIG. To access
these additional Registry hives in PowerShell, you use the Set-Location cmdlet to
change the location to the root of the Registry provider.
ptg
Because the Windows Registry is treated as a hierarchy data store, like the Windows file
system, it can also be managed by the PowerShell core cmdlets. For example, to read a
Registry value, you use the Get-ItemProperty cmdlet:
PS C:\> $Path = “HKLM:\Software\Microsoft\Windows NT\CurrentVersion”
PS C:\> $Key = get-itemproperty $Path
PS C:\> $Key.ProductName
Windows Server 2008 R2 Enterprise
PS C:\>
To create or modify a Registry value, you use the Set-ItemProperty cmdlet:
PS C:\> $Path = “HKCU:\Software”
PS C:\> set-itemproperty -path $Path -name “PSinfo” –type “String” –value “Power-
Shell_Was_Here”
PS C:\>
PS C:\> $Key = get-itemproperty $Path
PS C:\> $Key.PSinfo
PowerShell_Was_Here
PS C:\>
Remember that the Windows Registry has different types of Registry values. You use the
Set-ItemProperty cmdlet to define the Type parameter when creating or modifying Registry
values. As a best practice, you should always define Registry values when using the Set-
ItemProperty cmdlet. Otherwise, the cmdlet defines the Registry value with the default
type, which is String. Other possible types are as follows:
746
CHAPTER 21
Automating Tasks Using PowerShell Scripting
. ExpandString
. Binary
. DWord
. MultiString
. Qword
NOTE
Depending on the Registry value you’re creating or modifying, the data value you set
the named value to needs to be in the correct format. So, if the Registry value is type
REG_BINARY, you use a binary value, such as $Bin = 101, 118, 105.
To delete a Registry value, you use the Remove-ItemProperty cmdlet, as shown here:
PS C:\> $Path = “HKCU:\Software”
PS C:\> remove-itemproperty -path $Path -name “PSinfo”
PS C:\>
ptg
Managing Processes
In PowerShell, you can use two cmdlets to manage processes. The first cmdlet, Get-
Process, is used to get information about the current processes that are running on the
local Windows system:
PS C:\> get-process
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
782 12 2500 4456 113 4.02 448 csrss
237 10 3064 6228 113 76.70 488 csrss
292 26 20180 14632 356 12.94 1496 dfsrs
160 13 3020 5536 55 0.34 2696 dfssvc
203 24 6368 5888 64 1.75 3220 dns
...
To filter the object collection that is returned by the Get-Process cmdlet to a particular
process, you can specify the process name or ID, as shown in the following example:
PS C:\> get-process dns
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
203 24 6368 5888 64 1.77 3220 dns
Using Windows PowerShell
747
PS C:\> get-process -id 3220
21
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
203 24 6368 5888 64 1.77 3220 dns
PS C:\>
In addition to the preceding examples, you could also combine the Get-Process cmdlet
with the Where-Object cmdlet. For example:
PS C:\> get-process | ? {$_.workingset -gt 100000000} | sort ws -descending
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
471 29 108608 104972 658 95.88 4208 mmc
629 39 130716 104208 705 108.58 4332 mmc
PS C:\>
ptg
By using these cmdlets together, a more robust view of the current running processes
based on a specified filter statement can be created. In the previous example, the resulting
object collection includes processes that only have a working set greater than 100,000,000
bytes. In addition, the Sort-Object cmdlet is used to sort the formatted table’s WS(K)
column in descending order.
The second cmdlet that is used to manage processes is the Stop-Process cmdlet. Usage of
this cmdlet is as follows:
PS C:\work\logs> stop-process -name notepad
The process that is being stopped can either be defined by its name, ID, or as an object
that is passed to the Stop-Process cmdlet via the pipeline.
Using WMI
Using WMI in PowerShell has similar conceptual logic as in WSH. The main difference is
that the PowerShell methods are based on WMI .NET instead of the WMI Scripting API.
You have three methods for using WMI in PowerShell: WMI .NET (which is the .NET
System.Management and System.Management.Instrumentation namespaces), the Get-
WmiObject cmdlet, or the PowerShell WMI type accelerators: [WMI], [WMIClass], and
[WMISearcher].
The first method, using the System.Management and System.Management.Instrumentation
namespaces, isn’t discussed in this chapter because it’s not as practical as the other
methods. It should be only a fallback method in case PowerShell isn’t correctly encapsu-
lating an object within a PSObject object when using the other two methods.
748
CHAPTER 21
Automating Tasks Using PowerShell Scripting
The second method, the Get-WmiObject cmdlet, retrieves WMI objects and gathers infor-
mation about WMI classes. This cmdlet is fairly simple. For example, getting an instance
of the local Win32_ComputerSystem class just requires the name of the class, as shown here:
PS C:\> get-wmiobject “Win32_ComputerSystem”
Domain : companyabc.com
Manufacturer : Hewlett-Packard
Model : Pavilion dv8000 (ES184AV)
Name : Wii
PrimaryOwnerName : Damon Cortesi
TotalPhysicalMemory : 2145566720
PS C:\>
The next example, which is more robust, connects to the remote machine named Jupiter
and gets an instance of the Win32_Service class in which the instance’s name equals
Virtual Server. The result is an object containing information about the Virtual Server
service on Jupiter:
ptg
PS C:\> get-wmiobject -class “Win32_Service” -computerName “Jupiter” -filter
“Name=’Virtual Server’”
ExitCode : 0
Name : Virtual Server
ProcessId : 656
StartMode : Auto
State : Running
Status : OK
PS C:\>
The following command returns the same information as the previous one but makes use
of a WQL query:
PS C:\> get-wmiobject -computerName “Jupiter” -query “Select *From Win32_Service
Where Name=’Virtual Server’”
ExitCode : 0
Name : Virtual Server
ProcessId : 656
StartMode : Auto
State : Running
Status : OK
PS C:\>
Using Windows PowerShell
749
Finally, here’s an example of using Get-WmiObject to gather information about a WMI class: