Managing Files and Directories


File and directory management is a pretty common administrative task. Here are some ways to accomplish typical tasks using PowerShell.

Creating Text Files

In Chapter 9 we discussed how you can use console redirection to send output to a text file and how to using Out-File, so we won't go into detail. Instead, we'll provide a few examples for creating text files. First let's look at a line of code that redirects output to a text file:

 PS C:\> get-wmiobject win32_share > myshares.txt 

Remember > send output to the specified file, overwriting an existing file with the same name. Use >> to append to an existing file. The file will be created if it doesn't already exist.

Here's the same expression, but using the Out-File cmdlet:

 PS C:\> get-wmiobject win32_share | out-file myshares.txt -noclobber 

We used -NoClobber to prevent Out-File from overwriting myshares.txt, if it already exists.

Finally, you can also use New-Item to create a file and even add some content to it:

 PS C:\> $now=get-date PS C:\> new-item audit.log -type File -value "Created $now" -force     Directory: Microsoft.PowerShell.Core\FileSystem::C:\ Mode                LastWriteTime     Length Name ----                -------------     ------ ---- -a---         6/16/2006  10:40 AM         30 audit.log PS C:\> get-content audit.log Created 6/16/2006 10:40:30 AM PS C:\> 

In this example we use New-Item to create a file called audit.log and give it some content.

Reading Text Files

Reading text files is pretty straightforward with Get-Content:

 PS C:\> get-content boot.ini [boot loader] timeout=15 default=multi(0)disk(0)rdisk(0)partition(2)\WINDOWS [operating systems] multi(0)disk(0)rdisk(0)partition(2)\WINDOWS="Microsoft Windows XP Professional"  /fastdetect /NoExecute=OptIn multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Windows Server 2003, Enterprise" / noexecute=optout /fastdetect C:\CMDCONS\BOOTSECT.DAT="Microsoft Windows Recovery Console" /cmdcons PS C:\> 

We can use -TotalCount to display a specified number of lines from a text file:

 PS C:\> get-content ADOXEXCEPTION.LOG -TotalCount 5 CADOXCatalog Error         Code = 80040e4d         Code meaning = IDispatch error #3149         Source = Microsoft OLE DB Provider for SQL Server         Description = Login failed for user 'scriptaccess'. PS C:\> 

In this example, the first five lines of a log file are displayed. You can get the same result with this expression:

 PS C:\> get-content ADOXEXCEPTION.LOG |select-object -first 5 

An advantage to this approach is that Select-Object also has a -Last parameter that you can use to display a specified number of lines from the end of the file.

Copying Files

Copying files in PowerShell is not much different than copying files in Cmd.exe. In fact, by default PowerShell uses the alias Copy for the Copy-Item cmdlet.

 PS C:\> copy *.ps1 c:\temp PS C:\> get-childitem c:\temp     Directory: Microsoft.PowerShell.Core\FileSystem::C:\temp Mode                LastWriteTime     Length Name ----                -------------     ------ ---- -a---         5/17/2006   8:31 PM        863 brace.ps1 -a---         5/29/2006  12:18 PM         15 demo.txt -a---         2/11/2006   6:26 PM      19817 ex060211.log -a---         5/29/2006  10:58 AM         16 j.txt -a---         5/23/2006   1:03 PM        811 out-grid.ps1 -a---         5/23/2006   1:06 PM       1330 out-propertyGrid.ps1 -a---         5/19/2006  11:17 AM        710 showprocessinfo.ps1 -a---         5/19/2006  11:04 AM        477 showservices.ps1 -a---         5/1/2006    8:10 PM         88 test.ps1 PS C:\> 

This example copies all ps1 files in C: to C:\temp. You can also recurse and force files to be overwritten:

 PS C:\>copy-item C:\Logs C:\Backup -recurse -force 

This expression copies all files and subdirectories from C:\Logs to C:\Backup, overwriting any existing files and directories with the same name.

As you work with PowerShell, you'll discover that not every command you can execute in Cmd.exe is valid in PowerShell. For example, the following is a valid command in Cmd.exe:

 C:\logs> copy *.log *.old 

When you try this in PowerShell, you'll get a message about an invalid character. It appears the Copy-Item cmdlet works fine when copying between directories, but it can't handle a wildcard copy within the same directory.

Here's a work around:

BulkCopy.ps1

image from book
 #BulkCopy.ps1 Set-Location "C:\Logs" $files=Get-ChildItem |where {$_.extension -eq ".log"} foreach ($file in $files) {  $filename=($file.FullName).ToString()  $arr=@($filename.split("."))  $newname=$arr[0]+".old"  Write-Host "copying "$file.Fullname "to"$newname  copy $file.fullname $newname -force } 
image from book

With this script we first define a variable that contains all the files we want to copy by extension. Next we iterate through the variable using ForEach. Within the loop we break apart the filename using Split so we can get everything to the left of the period. We need this name so we can define what the new filename will be with the new extension, including the path. Then it's a matter of calling Copy-Item. Notice that in the script we're using the copy alias.

Provider Alert

If you look through the Help for Copy-Item and some of the other Item cmdlets, you will see a -Credential parameter. This might lead you to believe that you could use the -Credential parameter to copy files to a network and share and specify alternate credentials. Unfortunately, in the first version of PowerShell, the filesystem and registry providers do not support this parameter. Hopefully this will change in later versions of PowerShell. In the meantime, start a PowerShell session using the RunAs command if you need to specify alternate credentials.

Deleting Files

The Remove-Item cmdlet has aliases of del and erase, and functions essentially the same as these commands in Cmd.exe:

 PS C:\> remove-item c:\temp\*.txt 

The cmdlet comes in handy when you want to recurse through a directory structure or exclude certain files.

 PS C:\> remove-item c:\backup\*.* - recurse -exclude 2006*.log 

This expression will recurse through c:\backup deleting all files except those that match the pattern 2006*.log. Like Copy-Item, you can also use -Include and -Credential.

Renaming Files

Renaming files is also very straightforward:

 PS C:\Temp> rename-item foo.txt bar.txt 

This cmdlet has aliases of rni and ren, and like the other item cmdlets, it lets you specify credentials and force an overwrite of an existing file. You have to be a little more creative if you need to rename multiple files:

BulkRename.ps1

image from book
 #BulkRename.ps1 Set-Location "C:\Logs" $files=get-childitem -recurse |where {$_.extension -eq ".Log"} foreach ($file in $files) {  $filename=($file.name).ToString()  $arr=@($filename.split("."))  $newname=$arr[0]+".old"  Write-Host "renaming"$file.Fullname "to"$newname  ren $file.fullname $newname -force } 
image from book

This is a legitimate command in Cmd.exe:

 C:\ ren *.log *.old 

Since this doesn't work in PowerShell, we use something like the BulkRename script instead. This is a variation on our BulkCopy script from above. Instead of copy, we call ren. By the way, as the script is written above, it will recurse through subdirectories starting in C:\Logs, renaming every file it finds that ends in .log to .old.

Creating Directories

Creating directories in PowerShell is nearly the same as it is in Cmd.exe:

 PS C:\Temp> mkdir "NewFiles" 

Alternatively, you can use the New-Item cmdlet that offers a few more features:

 PS C:\Temp> new-item -type directory \\File01\public\sapien 

The cmdlet also creates nested directories. In other words, like mkdir in Cmd.exe, it creates any intermediate directories:

 PS C:\Temp> new-item -type directory c:\temp\1\2\3     Directory: Microsoft.PowerShell.Core\FileSystem::C:\temp\1\2 Mode                LastWriteTime     Length Name ----                -------------     ------ ---- d----         6/16/2006   1:56 PM            3 PS C:\Temp> tree /a Folder PATH listing for volume Server2003 Volume serial number is 0006EEA4 34AB:AD37 C:. +---1 |   \---2 |       \---3 +---jdh +---sapien \---temp2 PS C:\Temp> 

Listing Directories

Even though you can use dir in PowerShell to list directories and files, it is really an alias for Get-ChildItem. However, you can specify files to include or exclude in the search and also recurse through subdirectories:

 PS C:\> dir -exclude *.old -recurse 

Remember, even though PowerShell is displaying text, it is really working with objects. This means you can get creative in how you display information:

 PS C:\Temp> dir -exclude *.old,*.bak,*.tmp -recurse | select-object ` >>FullName,Length,LastWriteTime | format-table -auto >> FullName                          Length LastWriteTime --------                          ------ ------------- C:\Temp\1                                6/16/2006 1:56:45 PM C:\Temp\1\2                              6/16/2006 1:56:45 PM C:\Temp\1\2\3                            6/16/2006 1:56:45 PM C:\Temp\jdh                              6/16/2006 1:09:41 PM C:\Temp\sapien                           6/16/2006 1:05:41 PM C:\Temp\temp2                            6/16/2006 12:48:44 PM C:\Temp\temp2\bar.Log             11     6/16/2006 11:09:27 AM C:\Temp\showservices.ps1          477    5/19/2006 11:04:29 AM C:\Temp\test.abc                  88     5/1/2006 8:10:10 PM C:\Temp\test.Log                  88     5/1/2006 8:10:10 PM C:\Temp\test.ps1                  88     5/1/2006 8:10:10 PM PS C:\Temp> 

This expression recurses from the starting directory, listing all files that don't end in .old, .bak, or .tmp. Using the dir alias, the output from Get-Childitem is piped to Select-Object because we want to display only certain information formatted as a table.

Deleting Directories

Deleting a directory is essentially the same as deleting a file. You can use the rmdir alias for Remove-Item:

 PS C:\Temp> rmdir sapien 

PowerShell gives you a warning if you attempt to remove a directory that isn't empty:

 PS C:\Temp> rmdir files Confirm The item at C:\Temp\files has children and the -recurse parameter was not specified. If you continue, all children will be removed with the item. Are you  sure you want to continue? [Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"):n PS C:\Temp> 

As you can see, the solution is to use the -Recurse parameter:

 PS C:\Temp> rmdir files -recurse PS C:\Temp> 



Windows PowerShell. TFM
Internet Forensics
ISBN: 982131445
EAN: 2147483647
Year: 2004
Pages: 289

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net