PowerShell File Management

Every day, sysadmins have to perform various standard operations on the numerous files and folders on their Windows servers. These tasks often include managing users’ data on shared resources and maintaining backups properly. You can use PowerShell to reduce amount of manual work involved.

In this article, you will learn how to use PowerShell to:

Before you start, make sure your system policy allows running PowerShell scripts as described in “Windows PowerShell Scripting Tutorial for Beginners.”

Viewing the objects in a directory

To view the content of a directory on a Windows file server, use the Get-ChildItem cmdlet. To show all hidden files, add the -Force parameter. The command below shows all root objects in the Shared folder:

Get-ChildItem -Force \\fs\Shared

If you want to also check all subfolders and their content, add -Recurse parameter:

Get-ChildItem -Force \\fs\Shared -Recurse

To filter the output, add the Filter, Exclude, Include and Path parameters to the Get-ChildItem cmdlet. For advanced object filtering, use the Where-Object cmdlet. The script below searches for all executable files in the IT folder that were modified after April 1, 2018:

Get-ChildItem -Path \\fs\Shared\IT -Recurse -Include *.exe | Where-Object -FilterScript {($_.LastWriteTime -gt '2018-04-01')}

Creating files and folders with PowerShell

To create new objects with Windows PowerShell, you can use the New-Item cmdlet and specify the type of item you want to create, such as a directory, file or registry key.

For example, this command creates a folder:

New-Item -Path '\\fs\Shared\NewFolder' -ItemType Directory

And this command creates an empty file:

New-Item -Path '\\fs\Shared\NewFolder\newfile.txt' -ItemType File

Creating files and writing data to them

There are at least two built-in methods to create a file and write data to it. The first is to use the Out-File cmdlet:

$text = 'Hello World!' | Out-File $text -FilePath C:\data\text.txt

To overwrite an existing file, use the –Force switch parameter.

You can also create files using the Export-Csv cmdlet, which exports the output into a csv file that can be opened in Excel:

Get-ADuser -Filter * | Export-Csv -Path C:\data\ADusers.csv

Creating files after checking that they don’t already exist

The following script checks whether a specific file (pc.txt) already exists in a particular folder; if not, it generates a list of all AD computers and saves it to a new file named pc.txt:

#create array of text files
$files=Get-ChildItem C:\data\*.txt | select -expand fullname
#check if file exists inside the array
$files -match "pc.txt"
#if matching return “True” key then exit, if “False” then create a report
if($files -eq 'False'){
Get-ADComputer -Filter * | Export-Csv -Path C:\data\pc.txt

Deleting files and folders with PowerShell

To delete objects, use the Remove-Item cmdlet. Please note that it requires your confirmation upon execution if the object is not empty. The example below demonstrates how to delete the IT folder and all the subfolders and files inside it:

Remove-Item -Path '\\fs\shared\it\'
The item at \\pdc\shared\it 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"):

If you have already made sure that every object inside the folder should be deleted, you can use the ?Recurse switch to skip the confirmation step:

Remove-Item -Path '\\fs\shared\it\' -Recurse

Deleting files and folders older than X days

Sometimes you need to clean up old files from a certain directory. Here’s the way to accomplish that:

$Folder = "C:\Backups"

#delete files older than 30 days
Get-ChildItem $Folder -Recurse -Force -ea 0 |
? {!$_.PsIsContainer -and $_.LastWriteTime -lt (Get-Date).AddDays(-30)} |
ForEach-Object {
   $_ | del -Force
   $_.FullName | Out-File C:\log\deletedbackups.txt -Append

#delete empty folders and subfolders if any exist
Get-ChildItem $Folder -Recurse -Force -ea 0 |
? {$_.PsIsContainer -eq $True} |
? {$_.getfiles().count -eq 0} |
ForEach-Object {
    $_ | del -Force
    $_.FullName | Out-File C:\log\deletedbackups.txt -Append

Deleting files after checking they exist

Here’s how to check whether a file exists and delete it if it does:

$FileName = 'C:\data\log.txt'
If (Test-Path $FileName){
   Remove-Item $FileName

Deleting files from multiple computers in one script

To delete files from remote PCs, you must have the appropriate security permissions to access them. Be sure to use UNC paths so the script will correctly resolve the file locations.

$filelist = @(" \c$\Temp", "\c$\Backups") #variable to delete files and folder
$computerlist = Get-Content  C:\data\pc.txt #get list of remote pc's
    foreach ($computer in $computerlist){
        foreach ($file in $filelist){
            $filepath= Join-Path "\\$computer\" "$filelist" #generate unc paths to files or folders
            if (Test-Path $filepath)
            Remove-Item $filepath -force -recurse -ErrorAction Continue}}}

Copying files and folders with PowerShell

The Copy-Item cmdlet enables you to copy objects from one path to another. The following command creates a backup by copying the file users.xlsx from one remote computer (fs) and saving it to another (fs2) over the network:

Copy-Item -Path \\fs\Shared\it\users.xlsx -Destination \\fs2\Backups\it\users.xlsx

If the target file already exists, the copy attempt will fail. To overwrite the existing file, even if it is in Read-Only mode, use the -Force parameter:

Copy-Item -Path \\fs\Shared\it\users.xlsx -Destination \\fs2\Backups\it\users.xlsx -Force

Copying files with PowerShell to or from a remote computer

If you’re copying files to or from remote computers, be sure to use UNC paths.

For example, use this command to copy files from a remote file server to the local C: directory:

Copy-Item \\fs\c$\temp -Recurse C:\data\

To copy files from your local directory to the remote folder, simply reverse the source and destination locations:

Copy-Item C:\data\ -Recurse \\fs\c$\temp

Copying multiple files from one server to another over the network in one script

You can also copy files from one remote server to another. The following script recursively copies the \\fs\Shared\temp folder to \\fs\Shared\test:

Copy-Item \\fs\Shared\temp -Recurse \\fs\Shared\test

Copying only certain types of files

To copy only certain files from the source content to the destination, use the -Filter parameter. For instance, the following command copies only txt files from one folder to another:

Copy-Item -Filter *.txt -Path \\fs\Shared\it -Recurse -Destination \\fs2\Shared\text

Copying files using XCOPY and ROBOCOPY commands or COM objects

You can also run XCOPY and ROBOCOPY commands to copy files, or use COM objects as in the example below:

(New-Object -ComObject Scripting.FileSystemObject).CopyFile('\\fs\Shared', 'fs2\Backup')

Moving files and directories with PowerShell

The Move-Item cmdlet moves an item, including its properties, contents, and child items, from one location to another. It can also move a file or subdirectory from one directory to another location.

The following command moves a specific backup file from one location to another:

Move-Item -Path \\fs\Shared\Backups\1.bak -Destination \\fs2\Backups\archive\1.bak

This script moves the entire Backups folder and its content to another location:

Move-Item -Path \\fs\Shared\Backups -Destination \\fs2\Backups\archive

The Backups directory and all its files and subfolders will then appear in the archive directory.

Renaming files with PowerShell

The Rename-Item cmdlet enables you to change the name of an object while leaving its content intact. It’s not possible to move items with the Rename-Item command; for that functionality, you should use the Move-Item cmdlet as described above.

The following command renames a file:

Rename-Item -Path "\\fs\Shared\temp.txt" -NewName "new_temp.txt"

Renaming multiple files

To rename multiple files at once, use a script like this:

$files = Get-ChildItem -Path C:\Temp #create list of files
foreach ($file in $files)
    $newFileName=$file.Name.Replace("A","B")  #replace "A" with "B"
    Rename-Item $file $newFileName

Changing file extensions with PowerShell

You can also use the Rename-Item to change file extensions. If you want to change the extensions of multiple files at once, use the Rename-Item cmdlet with the Get-ChildItem cmdlet.

The following script changes all “txt” file extensions to “bak”. The wildcard character (*)ensures that all text files are included:

Get-ChildItem \\fs\Shared\Logs\*.txt | Rename-Item -NewName { $_.name -Replace '\.txt$','.bak' }

Using the information in this article, you can automate a variety of simple operations related to file management on your file storages and save time for more important tasks. Good luck!