Posts Tagged ‘ PowerShell ’

PowerShell to the rescue

It’s been a while since I last posted. A lot of things happened and changed since then. I finished university and got my master’s degree, started working full-time, and this resulted in less free time and more laziness. But let’s go back to the topic at hand.

I made a backup of a game bought on Steam, to play later, but Steam failed to restore it from the backup. Thinking that the backup was corrupt, I deleted it to free up some space. I later realized that it wasn’t the backup’s fault, but the Steam client’s and the backup was good, so I found a recovery software and tried to recover the backed up files. I hoped that the files haven’t been overwritten, because there wasn’t much new data written to the disk since I erased them.

If you have opened a Steam backup folder, then you know that it makes folders named Disk_{disk number}, each containing three files: {ID}_depotcache_{disk number}.csm, {ID}_depotcache_{disk number}.csd, and sku.sis. The Disk_1 folder is an exception, because it contains two additional files (a .csd and a .csm), with ID+1 as their ID. The backup software could only dump recovered files in a single directory, without recreating the original folder structure, which caused a problem with the sku.sis files, so I had to rename them by hand to sku_{disk number}.sis. I wrote a simple PowerShell script to recreate the folder structure, and put the files in their respective places. Here is the full script:

param ([string] $pathOfDisks)

$files = Get-ChildItem -Path $pathOfDisks -Include @("*.csm", "*.csd", "*.sis") -Recurse

$files | % {
    $nameNoExt = [System.IO.Path]::GetFileNameWithoutExtension($_)
    $lastUnderscore = $nameNoExt.LastIndexOf('_')
    $diskNumber = $nameNoExt.Substring($lastUnderscore + 1)

    if (![System.IO.Directory]::Exists("$pathOfDisks\Disk_$diskNumber")) {
        mkdir "$pathOfDisks\Disk_$diskNumber"
    }

    if ([System.IO.Path]::GetExtension($_) -eq ".sis") {
        Move-Item -Path $_ -Destination "$pathOfDisks\Disk_$diskNumber\sku.sis"
    } else {
        Move-Item -Path $_ -Destination "$pathOfDisks\Disk_$diskNumber\"
    }
}

The script fetches every file with a .csm, .csd, or .sis extension in the path provided as input parameter. Then it strips the disk number from the end of the file’s name, and moves the file in the right folder, creating the folder if it doesn’t exist yet. If the moved file is a .sis file, then it is also renamed to sku.sis.

The -Recurse parameter for Get-ChildItem is required by the -Include parameter to filter the folder contents to more than one criteria (that’s why using the -Filter parameter is a no-go).

Unfortunately some files were overwritten, so I had to download the game again, but writing this little script proved it again, that making PowerShell was a good decision by Microsoft. It provides a fast and powerful scripting environment for automating menial tasks such as bulk file moving.

I will try to write posts more regularly from now on, at least once a month, but hopefully more frequently than that. If you have any suggestions, then please comment!

Design a site like this with WordPress.com
Get started