left-icon

PowerShell Succinctly®
by Rui Machado

Previous
Chapter

of
A
A
A

CHAPTER 2

File System

File System


This chapter is specifically for system administrators who dedicate several hours in their daily routine to working with files and directories. PowerShell won´t free you from doing it, but it might help you automate your manual tasks by writing reusable functions.

Current Location

An important topic when dealing with files and directories is setting your paths. Current location is one of those important paths for you to create relative paths between files and even scripts. To get your current location, you use the Get-Location command, which retrieves an object that represents the current directory, much like the pwd (print working directory) command. In this object you have the current path and drive.

#Returns full path for the current location.

Get-Location | %{$_.Path}

#Return drive info.

Get-Location | %{$_.Drive}

Get-Location Execution

Get Files from a Directory

To retrieve information about all files in a directory, you can use the Get-ChildItem command, or if you just want to list information about a single item, use the Get-Item command. This command has several important parameters; three of them are highlighted in Table 5.

Table 5: Get-Item parameters

Parameter

Definition

-Name

Gets only the names of the items in the locations.

-Recurse

Gets the items in the specified locations and in all child items of the locations.

-Path

Specifies a path to one or more locations.

#Simple Get-ChildItem

Get-ChildItem -Path (Get-Location).Path

#Get-ChildItem using -Recurse parameter.

Get-ChildItem -Path (Get-Location).Path -Recurse

#Get-ChildItem using -Recurse parameter and a filter for file name (-Name)

Get-ChildItem -Path (Get-Location).Path -Name "*Rui*"

#Get-ChildItem filter by extension.

Get-ChildItem -Path (Get-Location).Path | ?{$_.Extension -like "*txt"}

Get the Content of a File

#Get the content of a single file without restrictions.

Get-Content -Path "c:\temp\File.txt"

Getting the content of a file is an easy task thanks to the Get-Content command, which will read the content one line at a time and return a collection of objects, each of which represents a line of its content. You can either invoke this command alone or combine it with the Get-ChildItem command to dynamically read the content of multiple files, according to its attributes such as last change date.

The previous code block shows you a simple example on how to retrieve the content of a single file. This will result in an object array with all lines red, which you can save into a variable and manipulate later. Figure 32 reproduces the result of this calling. To test this code block, create a file named File.txt in C:\temp.

Calling Get-Content

Your requirements might involve more elaborate callings. In the following code block there are several examples on how to use this command.

#Get the first three lines of your file using the -TotalCount parameter.

Get-Content -Path "c:\temp\File.txt" -TotalCount 3

#Get the last line of your file using the -Tail parameter (Available since Powershell v3.0)

Get-Content -Path "c:\temp\File.txt" -Tail 1

<#

     In this example combining this command with Get-ChildItem

     will allow you to retrieve the content of all files in c:\temp directory

#>

#Get the files

Get-ChildItem -Path "c:\temp" -Filter "*.txt" | %{

     #Get Content

     Get-Content -Path $_.FullName 

}

Manipulate the Content of a File

Once you have the content of a file, it is likely that you will want to change its content, either by cleaning it, replacing strings, or even adding text to it. The Set-Content command provides this ability by allowing you to write or replace the content of a specified item, such as a file. If you use this command alone and invoke it with only a path and value, then it will replace the entire content with the new one specified in the value parameter. To replace text in a file, you need to combine it with the Get-Content command.

In the following example, we will get the content of a file and replace every instance of the string “_(TOCHANGE)” with the string “PowerShell”. The original text inside the file is the following:

“_(TOCHANGE) Hello _(TOCHANGE) Fans. This is a Get-Content example made for Syncfusion Succinctly Series by Rui Machado”

Now we will run the following script to change the file content to the correct sentence. Note that what will change the content of the file is the string replace made after reading the content of the file. The Set-Content command will just take the path of the file and the new value for its content passed through the pipeline.

#File path.

$path = "c:\temp\File.txt"

#Get the file content.

Get-Content -Path $path | %{

     #Replace the token in memory, this won’t change the file content.

     $new = $_.Replace("_(TOCHANGE)","PowerShell")

}

#Set the file content.

Set-Content -Path $path -Value $new

This will result in a content reset for our file as you can see in the following figure.

Reset file content

Create Temporary Files

Using temporary files is a useful strategy for manipulating files across several script invocations. For instance, you can create a temporary XML file and manipulate it using several function and method calls and then save it only at the end of your script execution.

To create a temporary file, you can use the .NET namespace that handles paths, [System.IO.Path] which among other things includes a method called GetTempFileName()for creating temporary files.

#This gives you a temp url file to work with.

$url = [System.IO.Path]::GetTempFileName()

#After getting the temp url, you can work with the file.

"Rui" | Out-File $url

#You can retrieve the content of the temp file.

Get-Content $url

Manage Directories

Create New Directories

Managing directories includes tasks such as creating new directories, deleting directories, changing permissions, and renaming directories. PowerShell allows you to use the common MS-DOS commands to manage directories, but it adds new commands so that managing directories becomes easier, faster, and more efficient.

To create a new directory in the old Windows shell you use mkdir. PowerShell redefines the mkdir command by offering you the New-Item command. The New-Item command is not only used to create directories, but can also be used to create files, registry keys, and entries. New-Item takes a –type parameter that determines the type of item to create.

To create a new directory, you just need to invoke the command New-Item, providing as parameters its destination path and the type directory parameters.

New-Item  -Path "c:\temp\newFolder" -ItemType Directory

Create a new directory

Change Directory Permissions

Although the directory is already created, you might want to change its permissions. To do so, you must be aware of the access control list (ACL) concept, which is a list of access control entries (ACE) that identifies a trustee and specifies the access rights allowed, denied, or audited for that trustee. In another words, it specifies the permissions that users and user groups have to access a specific resource.

PowerShell allows you to get and set the ACL for a file or directory, and to do so you can use the Get-Acl command to retrieve objects that represent the security descriptor of a file or resource and the Set-Acl command to change the security descriptor of a specified item. The following code block shows how you can change the “newFolder” created previously to deny access to the users group.

$pathToFolder = "c:\temp\newFolder"

#Get the ACL of the folder.

$acl = Get-Acl -Path $pathToFolder

#set the new permission settings.

$perSettings = "BUILTIN\Users","FullControl","Deny"

#create the access rule.

$newRule = New-Object System.Security.AccessControl.FileSystemAccessRule $perSettings

#change the acl access rule.

$acl.SetAccessRule($newRule)

#Set the new rules in the folder ACL.

$acl | Set-Acl $pathToFolder

This will add a new entry in the permissions for this folder as you shown in Figure 35.

Change directory permissions

To get the output displayed in the previous figure, run the following code:

$acl = Get-Acl -Path $pathToFolder

$acl.Access | Out-GridView

Remove Directories

To remove a directory, you can use the command Remove-Item which is similar in behavior and calling structure to the New-Item command. In this case you just need to provide the item path without providing the item type.

Remove-Item  -Path "c:\temp\newFolder"

Combining the Get-ChildItem with Remove-Item command will allow you to create mechanisms of batch deletion of files inside directories according to a filter or file attribute.

The last manipulation task I want to talk about is renaming your files and directories. PowerShell also offers you a command to rename your files, which can be combined with the Get-ChildItem command, if you are working with sets of files in order, to rename several at once according to a given filter or file attribute.

Rename Directories

The Rename-Item command changes the name of a specified item. This command does not affect the content of the item being renamed. To use it, you just need to provide as a parameter the path to the destination directory or file and the new name to set.

#directory path

$path = "c:\temp\"

#This example will invoke the rename command to a set of files.

Get-ChildItem -Path $path -Name "File.txt" | %{

     #Rename the file.

     Rename-Item -Path  "$path\$_" -NewName "FileRenamed.txt"

}

#Simple use of rename item command.

Rename-Item -Path "$path\FileRenamed.txt" -NewName "File.txt"

Move a File or a Directory

To move a file or a directory, you can use the Move-Item command, which moves an item, including its properties, contents, and child items, from one location to another location. An important note to retain is that when you move an item, it is added to the new location and deleted from its original location.

#original file location. Where we want to move from.

$original = "c:\temp\File.txt"

#file target location. Where we want to move to.

$destination = "c:\temp\newFolder\File.txt"

#Invoke the move item command.

Move-Item -Path $original -Destination $destination

<#Path and destination are positional parameters 1 and 2 so you can ignore parameter referencing.

     Move-Item $original $destination

#>

#Move the entire directory.

Move-Item "c:\temp\newFolder" "c:\"

Managing Paths

Join Parts into a Single Path

PowerShell comes out of the box with great mechanisms to manage paths in your scripts, using operations like creating full paths by joining its relative parts, testing if a path exists, completing a relative path, or even splitting a path into its multiple parts.

For the task of joining multiple path parts, you can use the Join-Path command, which combines a path and child path into a single path. The provider supplies the path delimiters.

#This will return c:\temp\File.txt

Join-Path -Path "c:\temp" -ChildPath "File.txt"

#Because path and childpath are positional parameters (Path is 1 and ChildPath is 2) ignore the parameter reference.

Join-Path "c:\temp" "File.txt"

#Join multiple parts.

Join-Path (Join-Path "c:" "temp") "File.txt"

Split Paths into multiple parts

But what about the opposite task, splitting a path into multiple parts? To do that, you need to use the Split-Path command. This will return the specified part of a path that you defined in your command call, either the leaf (the last part of the part) or the head (the default behavior).

$path = "c:\temp\File.txt"

#Return the head of the path: c:\

Split-Path -Path $path

#Return the leaf of the path: File.txt

Split-Path -Path $path -leaf

#Split multiple times: temp

Split-Path (Split-Path -Path $path) -leaf

To enrich your split path command, you can use some .NET methods to get a file name or extension, a behavior that Split-Path won’t support.

$path = "c:\temp\File.txt"

#Return the file name: File.txt

[System.IO.Path]::GetFileName($path)

#Return the file extension: .txt

[System.IO.Path]::GetExtension($path)

#Return the file name without extension: File

[System.IO.Path]::GetFileNameWithoutExtension($path)

#Return the full file name: c:\temp\File.txt

[System.IO.Path]::GetFullPath($path)

#Return the directory name: c:\temp

[System.IO.Path]::GetDirectoryName($path)

Test if Path Exists

While accessing a particular file, you may want to change or get its content. It is a good idea to check and see if the file or directory exists. To accomplish this, PowerShell has the Test-Path command, which determines whether or not all elements of the path exist. It returns true ($true) if all elements exist and false ($false) if any are missing. It can also tell whether the path syntax is valid and whether the path leads to a container or a terminal (leaf) element.

This command is often used in combination with other commands as you see in the following code block.

$path = "c:\temp\File.txt"

#Simple path test, returns: True

Test-Path -Path $path

#You can evaluate the path forcing it to check if it is a file: True

Test-Path -Path $path -PathType Leaf

#You can evaluate the path forcing it to check if it is a directory: False

Test-Path -Path $path -PathType Container

#combine it with the Get-Content commands.

$found=(Test-Path -Path $path -PathType Leaf)

#if it is found, retrieve the content of the file.

if($found){

     Get-Content $path

}

     

Resolve Paths

The last task I want to mention in this managing path section is the ability to resolve paths dynamically in PowerShell. Resolving paths means interpreting wildcard characters in a path and displaying the path contents. To do this, you need to use the Resolve-Path command, which interprets the wildcard characters given and displays the items and containers at the location specified by the path, such as the files and folders or registry keys and sub keys.

#Target Directory

$path = "c:\temp\*"

#Get all files inside that directory.

Resolve-Path -Path $path

#Once again path is a positional parameter in position 1, so ignore parameter reference.

Resolve-Path $path     

By calling the previous script, PowerShell will list, according to the wildcard defined, all files inside the given path.

Result of Resolve-Path calling

Scroll To Top
Disclaimer
DISCLAIMER: Web reader is currently in beta. Please report any issues through our support system. PDF and Kindle format files are also available for download.

Previous

Next



You are one step away from downloading ebooks from the Succinctly® series premier collection!
A confirmation has been sent to your email address. Please check and confirm your email subscription to complete the download.