Showing posts with label Powershell. Show all posts
Showing posts with label Powershell. Show all posts

Tuesday, 2 August 2011

Powershell Find Rar files

Script purpose
Find all rar files in a folder and child folders. Then use the Extract-RAR-File function to decompress and remove the rar files.

Script notes
The rar files are matched using the regular expression ".*(?:(?<!\.part\d\d\d|\.part\d\d|\.part\d)\.rar|\.part0*1\.rar)". This could be improved as it matches all rar files and not just the first one is a set. I forget where found this regexp, Thanks to those who wrote it.
I excluded rar files in folders named trash as these have already been extracted.

function Extract-RARs-in-Folder([string]$Folder) {
<#
    .Synopsis
        Extracts all the rar files in the folder
    .Description
    .Example
        Extract-RARs-in-Folder C:\temp\
        would extract C:\temp\foo.rar and C:\temp\bar.rar
    .Parameter Folder
        Path of folder to be processed 
  .Link
        http://heazlewood.blogspot.com
#>
    #reference to source folder
    $basketFolder = get-item -LiteralPath $Folder   

    #Search the basket folder for any rar files
    $rarFiles = get-Childitem -LiteralPath $basketFolder.FullName -recurse |  
    where{$_.Name -match ".*(?:(?<!\.part\d\d\d|\.part\d\d|\.part\d)\.rar|\.part0*1\.rar)"} 
        
    foreach ($rarfile in $rarFiles)
    { 
        #if none are found an empty object is returned filter these by checking if the object exists
        if ($rarfile.Exists -eq $true)
        {
            write-verbose "processing matched rar : $($rarfile.Name)"
            if ($rarfile.Directory.Name -ne "Trash" )
            { 
                #this is a hack needed because I remove or move rar files in the Extract-RAR-File function.
                #regexp should be updated to only match on the first file of a span so this is not needed
                if (Test-Path $rarfile.Fullname  ) 
                {
                    $result = Extract-RAR-File $rarfile.FullName $true
                }
            }
            else
            {
                write-verbose "skipping item due to folder name$($_.FullName)"
            }
        }
    }
}

Powershell Folder Size

Powershell Folder Size

Script purpose
Calculate the size in bytes of a folder.

Script notes
I have some scripts that move folders from one drive to another or one pc to another. I use this to log size of folders that I move, before and after the move is completed.
The second script displays the bytes in a more user/log friendly manner.

function Get-FolderSize([string]$FolderPath) {
<#
    .Synopsis
        gets the folder size recursive
    .Example
        [long]$result = Get-FolderSize "C:\temp"
    .Parameter Source
    .Link
        http://heazlewood.blogspot.com/
#>
    [long]$FolderLength = (Get-ChildItem -LiteralPath $FolderPath -Recurse | Measure-Object -Property Length -Sum).Sum
    return $FolderLength 
}

#
function Get-BytesasString([long]$Bytes) {
<#
    .Synopsis
        Displays the bytes in a pretty way
    .Link
        http://heazlewood.blogspot.com/
#>
    if ($Bytes -gt 1073741823)
    {
        [Decimal]$size = $Bytes / 1073741824
        return "{0:##.##} GB" -f $size 
    }
    elseif ($Bytes -gt 1048575)
    {
        [Decimal]$size = $Bytes / 1048576
        return "{0:##.##} MB" -f $size
    }
    elseif ($Bytes  -gt 1023)
    {
        [Decimal]$size  = $Bytes / 1024
        return "{0:##.##} KB" -f $size
    }
    elseif ($Bytes -gt 0)
    {
        [Decimal]$size = $Bytes
        return "{0:##.##} bytes" -f $size
    }
    else
    {
        return "0 bytes";
    }
}

Powershell backup folder

Script purpose
Create a copy of a folder appending the current date and time to the newly created folder.

Script notes
Script is straight forward. A new folder (named FolderName-backupyyyyMMdd-hhmm) is created in the same path as the source folder. All the files are copied from the source to the new folder.

I use this to create a backup of my scripts on my dev pc before I sign and deploy them.

function Backup-Folder([string]$FolderPath)
{
<#
    .Synopsis
        Creates a back up copy of a folder
    .Description
    .Example
        Backup-Folder "C:\temp\folder1"
        Creates a folder "C:\temp\folder1-backupyyyyMMdd-hhmm"
    .Parameter FolderPath
        Path of folder that will be backed up
    .Link
        http://heazlewood.blogspot.com/
#>
  if (test-path -LiteralPath $FolderPath) {
 $FolderToCopy = Get-Item $FolderPath
 $newPath = Join-Path "$($FolderToCopy.Parent.FullName)" "$($FolderToCopy.Name)-backup_$((get-date).toString('yyyyMMdd-hhmm'))"
    
 Write-Host "copy $($FolderToCopy.FullName) to $newPath"
    
 copy -LiteralPath $FolderPath -Destination "$newPath" -Recurse -Force
  }
}

Monday, 1 August 2011

Powershell unrar

Script purpose
Uncompress a rar or set of rar files using unrar.exe. Once successfully completed remove the original rar files.

Script Notes
Files are extracted to the same folder as the rar file.

Success is determined by checking the output of the unrar executable. If it is successful there should be the text 'All OK' in the output. Files are only removed if this text is found on a single line by itself.

Rar files to be deleted are extracted from the output of the unrar executable.

The RemoveSuccessful parameter was added for testing. If set to false rar files will be moved to sub folder called trash, otherwise they are deleted.

Script
$Script:unrarName =  "path to unrar.exe"
 
function Extract-RAR-File([string]$FilePath, [bool]$RemoveSuccessful= $false) 
{
<#
    .Synopsis
        unrars a file or set of rar files, then if "all ok" 
        removes or moves the original rar files
    .Example
        Extract-RAR-File c:\temp\foo.rar
        Extracts contents of foo.rar to folder temp.
    .Parameter FilePath
        path to rar file 
    .Parameter RemoveSuccessful
        remove rar files if successful otherwise move files to folder called trash
    .Link
        http://heazlewood.blogspot.com
#>
    
    # Verify we can access UNRAR.EXE .
 if ([string]::IsNullOrEmpty($unrarName) -or (Test-Path -LiteralPath $unrarName) -ne $true)
 {
     Write-Error "Unrar.exe path does not exist '$unrarPath'."
        return
    }
 
    [string]$unrarPath = $(Get-Command $unrarName).Definition
    if ( $unrarPath.Length -eq 0 )
    {
        Write-Error "Unable to access unrar.exe at location '$unrarPath'."
        return
    }

   # Verify we can access to the compressed file.
 if ([string]::IsNullOrEmpty($FilePath) -or (Test-Path -LiteralPath $FilePath) -ne $true)
 {
     Write-Error "Compressed file does not exist '$FilePath'."
        return
    }
 
    [System.IO.FileInfo]$Compressedfile = get-item -LiteralPath $FilePath 
    
    #set Destination to basepath folder
    #$fileBaseName = [System.IO.Path]::GetFileNameWithoutExtension($Compressedfile.Name)
    #$DestinationFolder = join-path -path $Compressedfile.DirectoryName -childpath $fileBaseName
    
    #set Destination to parent folder
    $DestinationFolder = $Compressedfile.DirectoryName 

    # If the extract directory does not exist, create it.
    CreateDirectoryIfNeeded ( $DestinationFolder ) | out-null

    Write-Output "Extracting files into $DestinationFolder"
    &$unrarPath x -y  $FilePath $DestinationFolder | tee-object -variable unrarOutput 
    
    #display the output of the rar process as verbose
    $unrarOutput | ForEach-Object {Write-Verbose $_ }
     
    if ( $LASTEXITCODE -ne 0 )
    { 
        # There was a problem extracting. 
        #Display error
        Write-Error "Error extracting the .RAR file" 
    }
    else
    {
        # check $unrarOutput to remove files
        Write-Verbose "Checking output for OK tag"  
        if ($unrarOutput -match "^All OK$" -ne $null) {
            if ($RemoveSuccessful) {
                Write-Verbose "Removing files"  
                
                #remove rar files listed in output.
                $unrarOutput -match "(?<=Extracting\sfrom\s)(?<rarfile>.*)$" | 
                ForEach-Object {$_ -replace 'Extracting from ', ''} | 
                ForEach-Object { get-item -LiteralPath $_ } | 
                remove-item
                
            } else {
                Write-Verbose "Moving files to trash folder`n$trashPath"  
        
                [string]$trashPath = join-path -path $DestinationFolder "Trash"
                
                #create trash folder to move rars to
                CreateDirectoryIfNeeded ($trashPath)
                
                #move rar files listed in output.
                $unrarOutput -match "(?<=Extracting\sfrom\s)(?<rarfile>.*)$" | 
                ForEach-Object {$_ -replace 'Extracting from ', ''} | 
                foreach-object { get-item -LiteralPath $_ } | 
                move-item -destination $trashPath
            }
        }
    }
}

function CreateDirectoryIfNeeded ( [string] $Directory ){
<#
    .Synopsis
        checks if a folder exists, if it does not it is created
    .Example
        CreateDirectoryIfNeeded "c:\foobar"
        Creates folder foobar in c:\
    .Link
        http://heazlewood.blogspot.com
#>
    if ((test-path -LiteralPath $Directory) -ne $True)
    {
        New-Item $Directory-type directory | out-null
        
        if ((test-path -LiteralPath $Directory) -ne $True)
        {
            Write-error ("Directory creation failed")
        }
        else
        {
            Write-verbose ("Creation of directory succeeded")
        }
    }
    else
    {
        Write-verbose ("Creation of directory not needed")
    }
}

I have used this quite a bit, on various different files successfully but try with parameter RemoveSuccessful = $false first (its sure to have bugs). If you have any suggestions please share.

Links
Unrar download page http://www.rarlab.com/rar_add.htm

Chris