In this part we’ll start writing some Powershell. Initially we’ll write about the function call and function structure (see below). The full script can be found here.
function Move-Archive { [CmdletBinding()] param ( [Parameter(ValueFromPipeline=$true)] [string[]]$Folder="", [ValidateScript( { if(!(Test-Path $_ -PathType Container)) { Throw "SourcePath must be a valid path to a folder." }else { $True } } )] [string]$SourcePath="C:\Source", [ValidateScript( { if(!(Test-Path $_ -PathType Container)) { Throw "ArchivePath must be a valid path to a folder." }else { $True } } )] [string]$ArchivePath="E:\Target" ) BEGIN { } PROCESS { } END { } }
Some additional detail on the code follows
Function Name and Attributes
function Move-Archive { [CmdletBinding()]
Powershell cmdlets have a standard Verb-Noun structure (such as Get-ChildItem or Set-Mailbox) so I’m sticking with that for the function name.
The CmdletBinding attribute makes the function behave like a standard Powershell cmdlet in many ways. The main thing we want it for is to allow me to use Write-Verbose.
A rule of thumb with Powershell is to not write output to the host; instead all output should be in the form of objects. These can then be filtered or streamed to other cmdlets in the standard Powershell fashion.
That said, it can be useful to get additional output in certain circumstances and that’s where Write-Verbose comes in. If you call a compatible function with the –Verbose switch any statements written with Write-Verbose get written to the output. Additionally, any other cmdlets in the script will show more detailed output where applicable.
Function Parameters
param ( [Parameter(ValueFromPipeline=$true)] [string[]]$Folder="",
Here the parameter block for the function is started and the first parameter (Folder) is defined. This is going to be the folder we want archived or returned from archive. Ideally we want it to behave in the following way;
- The user should be able to pass a full path to a folder to process.
- It should also be able to pass just a folder name (or part name) which is then found in the source path (see parameter below).
- This parameter can be empty; if so all the folders in the source path are listed for processing and user can pick which ones to process.
- It should be able to process an empty parameter, a single string, an array of strings (a parameter in the format; (“Quake”, “World of Warcraft”) for example) or accept strings from the pipeline such as;
“Quake”, “World of Warcraft” | Move-Archive
In the code above [Parameter(ValueFromPipeline=$true)] states that the parameter succeeding it will accept input from the pipeline while [string[]]$Folder=”” states that the parameter is expecting an array of strings and that it should default to an empty string if the parameter isn’t passed.
[ValidateScript( { if(!(Test-Path $_ -PathType Container)) { Throw "SourcePath must be a valid path to a folder." }else { $True } } )] [string]$SourcePath="C:\Source",
The next parameter is the source path. This is the path to the folder holding all the folders we might want to archive or de-archive. The code above takes a string input and checks (using the code within [ValidateScript()] )that either it is a valid path to a folder OR it is empty (in which case the default folder “C:\Source” is used). If the parameter is passed and it’s not a valid path to a folder the script will throw an exception and stop.
[ValidateScript( { if(!(Test-Path $_ -PathType Container)) { Throw "ArchivePath must be a valid path to a folder." }else { $True } } )] [string]$ArchivePath="E:\Target" )
This is similar to the above code except for the archive path where folders will be archived to (or de-archived from). It also ends the parameter block.
Function Body
BEGIN { } PROCESS { } END { } }
This is where the main code for the function will go. In a function that can take pipeline input the code within Begin is only run once before the first element in the pipeline is processed. Code within Process is run for each element and the code within End is run once after the last element in the pipeline has finished processing. The final } closes the function.
In the next part we’ll begin writing the functions we’ll need for the script; starting with Get-FolderSize.