Export-ArchiveFile.ps1
<#
.SYNOPSIS Export and Archive files. .DESCRIPTION The Export-Archive command can be used to archive files. If required zipped and packaged into a single file. .PARAMETER SourcePath The Source file path that file/s need to be Exported. This path needs to be a folder .PARAMETER DestinationPath The Destination path the Exoported files need to be Copied/Moved .PARAMETER FileType File Type to archive. Multiple file types are supported with comma separation Example “*.csv,*ps1,*.log” .PARAMETER ArchiveFilesOlderthan Export files older than the specified number of days. Example if all files older than 10 days needs to be exported. use value of 10 .PARAMETER ArchiveToZip This optional parameter is used to specify if the destination exported file/s needs to be zipped. If this parameter is specified the ArchiveFilename parameter is Visible. .PARAMETER ArchiveFileName If the ArchiveToZip parameter is specified. This parameter is enabled. Use this optional parameter to specify the Zip file name .PARAMETER DeleteFilesFromSource If this optional parameter is specified files from the source directory is deleted(removed) after file has been exported .PARAMETER Verify This parameter is used to verify that the source and destination files match on completion of the export process. The output of this will only be displayed if the -verbose switch is used .PARAMETER Recurse Indicates that this gets the items in the specified locations and in all child items of the locations. .PARAMETER Force Indicates that this command will overwrite items that cannot otherwise be changed, such as copying over a read-only file or alias. .EXAMPLE Export-ArchiveFile -SourcePath C:\scripts\ -DestinationPath C:\test\ -FileType "*.csv" -ArchiveFilesOlderthan 20 -ArchiveToZip - -Verify -Force -Recurse -Verbose .EXAMPLE Export-ArchiveFile -SourcePath C:\scripts\ -DestinationPath C:\test\ -FileType "*.csv" -ArchiveFilesOlderthan 20 -ArchiveToZip -ArchiveFileName Test.zip -Verify -Force -Recurse -Verbose .NOTES The Export-Archive can be used to archive all files and subfolders. If the -force switch is used all duplicate files will be overwritten in the destination If the -force switch is used in conjunction with -ArchiveToZip the Zip file will be overwritten and updated If the -force switch is used in conjunction with - DeleteFilesFromSource the files will be deleted from the source even if file verification on both source and destination do not match #> Function Export-ArchiveFile { [cmdletbinding(DefaultParameterSetName='None')] param( [parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True,Mandatory=$True,HelpMessage="Log File Path",Position=0,ParameterSetName="Archive")] [ValidateScript({test-path -path $_ -type container})] [string]$SourcePath, [parameter(ValueFromPipelineByPropertyName=$True,Mandatory=$True,HelpMessage="Destination file path",ParameterSetName="Archive")] [ValidateScript({test-path -path $_ -type container})] [string]$DestinationPath, [parameter(ValueFromPipelineByPropertyName=$True,Mandatory=$True,HelpMessage="File Type to Archive, Example `"*.txt,*.csv`"",Position=1,ParameterSetName="Archive")] [string[]]$FileType, [parameter(ValueFromPipelineByPropertyName=$True,Mandatory=$True,HelpMessage="Log files to archive in days",Position=2,ParameterSetName="Archive")] [int]$ArchiveFilesOlderthan, [parameter(ValueFromPipelineByPropertyName=$True,Mandatory=$false,HelpMessage="zip Archive Folder",ParameterSetName='Archive',Position=3)] [switch]$ArchiveToZip, [parameter(ValueFromPipelineByPropertyName=$True,Mandatory=$false,HelpMessage="Archive file name",ParameterSetName='Archive',Position=4)] [switch]$DeleteFilesFromSource, [parameter(ValueFromPipelineByPropertyName=$True,Mandatory=$False,HelpMessage="verify that all files have been archived",ParameterSetName="Archive")] [switch]$Verify, [parameter(ValueFromPipelineByPropertyName=$True,Mandatory=$False,HelpMessage="recurse through all subfolders",ParameterSetName="Archive")] [switch]$Recurse, [parameter(ValueFromPipelineByPropertyName=$True,Mandatory=$False,HelpMessage="Force file overwrite",ParameterSetName="Archive")] [switch]$Force ) DynamicParam{ if($ArchiveToZip -eq $True){ $ParameterName = 'ArchiveFileName' $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute $ParameterAttribute.Mandatory = $False $ParameterAttribute.Position = 6 $ParameterAttribute.ParameterSetName ="Archive" $AttributeCollection.Add($ParameterAttribute) $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection) $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter) return $RuntimeParameterDictionary }#IF } BEGIN{ if($ArchiveToZip -eq $True){ $ArchiveFileName = $PSBoundParameters[$ParameterName] }#IF Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] Starting: $($MyInvocation.MyCommand)" Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] PSVersion = $($PSVersionTable.PSVersion)" Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] OS = $((Get-CimInstance win32_OperatingSystem).Caption)" Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] User = $($env:userdomain)\$($env:USERNAME)" $id = [System.Security.Principal.WindowsIdentity]::GetCurrent() $IsAdmin = [System.Security.Principal.WindowsPrincipal]::new($id).IsInRole('administrators') Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] Is Admin = $IsAdmin" }#BEGIN PROCESS{ #initialize variable $ExportZipFileName = $null #check and remove extra \ from source path if specified $SourcePath = $SourcePath -replace "\\$" #check and remove extra \ from Destination path if specified $DestinationPath = $DestinationPath -replace "\\$" #Split the file types so it can be passed into get-childitem $FileType = $FileType -split "," $ArchiveDateDate = (Get-Date).AddDays(-$ArchiveFilesOlderthan) if($Recurse.IsPresent) { Write-Verbose "Recurse switch detected" Get-ChildItem -Path $SourcePath\* -Include $FileType -Recurse | Where-Object {$_.LastWriteTime -le $ArchiveDateDate} -OutVariable FilesToArchive | Out-Null }#IF else { Get-ChildItem -Path $SourcePath\* -Include $FileType | Where-Object {$_.LastWriteTime -le $ArchiveDateDate} -OutVariable FilesToArchive | Out-Null }#Else if(!$FilesToArchive){ Write-Verbose "No files to Archive" }#IF else{ $Count = $FilesToArchive.count for($i=0 ;$i -lt $Count;$i++){ Write-Progress -Activity "File Archive Progress" -Status "File: : $($FilesToArchive[$i].Name)" -PercentComplete ($i/$Count*100) $DestinationFilePathToCopy = $DestinationPath + ($FilesToArchive[$i].FullName | Split-Path -NoQualifier) Write-Verbose "$($FilesToArchive[$i].Name) is older than $($ArchiveFilesOlderthan) days and will be Exported" if((Test-Path $DestinationFilePathToCopy -PathType Leaf) -eq $False){ Write-Verbose "$($FilesToArchive[$i].Name) does not exist and will be created" New-Item -Path $DestinationFilePathToCopy -ItemType File -Force | Out-Null }#IF elseif (!$Force.isPresent){ Write-Verbose "$($FilesToArchive[$i].Name) already exists in destination and will not be overwritten" continue }#Elseif Write-Verbose "Moving $($FilesToArchive[$i].Name) to $($DestinationPath)" switch($DeleteFilesFromSource) { true{ Write-Verbose "DeleteFilesFromSource switch detected" Move-Item $($FilesToArchive[$i].FullName) -Destination $DestinationFilePathToCopy -Force | Out-Null -ErrorAction Stop }#True false{ Copy-Item $($FilesToArchive[$i].FullName) -Destination $DestinationFilePathToCopy -Force | Out-Null -ErrorAction Stop }#False }#Switch }#for }#Else if($ArchiveToZip.IsPresent){ Write-Verbose "Archive to zip switch detected" $CurrentPath = ($FilesToArchive[0].DirectoryName | Split-Path -NoQualifier) $TopLevelZipPath = $CurrentPath -split '\\' $ZipFilePath = $DestinationPath+"\"+$TopLevelZipPath[1] if($ArchiveFileName){ $FileStatus = ((Test-Path -Path $DestinationPath\$ArchiveFileName".zip" -PathType Leaf)) switch($FileStatus) { True { if($Force.IsPresent) { Write-Verbose "Creating zip $($DestinationPath)\$($ArchiveFileName).zip" Compress-Archive -Path $ZipFilePath -DestinationPath $DestinationPath\$ArchiveFileName -Update -CompressionLevel Optimal $ExportZipFileName = "$($DestinationPath)\$($ArchiveFileName)" }#if else{ Write-Verbose "cannot create zipfile $($DestinationPath)\$($ArchiveFileName).zip already exists" continue }#else }#True False { Write-Verbose "Creating zip $($DestinationPath)\$($ArchiveFileName).zip" Compress-Archive -Path $ZipFilePath -DestinationPath $DestinationPath\$ArchiveFileName -force -CompressionLevel Optimal $ExportZipFileName = "$($DestinationPath)\$($ArchiveFileName)" }#False }#Switch }#IF else { #If an Archive file name is not spcified the Source folders top level folder will be used as the zip file name $NewArchiveFileName = $TopLevelZipPath[1] $FileStatus = ((Test-Path -Path $DestinationPath\$NewArchiveFileName".zip" -PathType Leaf)) switch($FileStatus) { True { if($Force.IsPresent) { Write-Verbose "Creating zip $($DestinationPath)\$($NewArchiveFileName).zip" Compress-Archive -Path $ZipFilePath -DestinationPath $DestinationPath\$NewArchiveFileName -Update -CompressionLevel Optimal $ExportZipFileName = "$($DestinationPath)\$($NewArchiveFileName)" }#if else{ Write-Verbose "cannot create zipfile $($DestinationPath)\$($NewArchiveFileName).zip already exists" continue }#else }#True False { Write-Verbose "Creating zip $($DestinationPath)\$($NewArchiveFileName).zip" Compress-Archive -Path $ZipFilePath -DestinationPath $DestinationPath\$NewArchiveFileName -force -CompressionLevel Optimal $ExportZipFileName = "$($DestinationPath)\$($NewArchiveFileName)" }#False }#Switch }#else }#IF For($i=0;$i -lt $FilesToArchive.Count;$i++){ $Properties = [ordered]@{ "FileName" = $FilesToArchive[$i] "Location" = $DestinationPath "LastWriteTime" =$FilesToArchive[$i].LastWriteTime }#Properties $FilesProcessed = New-Object -TypeName psobject -Property $Properties $FilesProcessed }#For if($ArchiveToZip.isPresent){ Write-Verbose "Total Files Exported $($FilesToArchive.Count)" Write-Verbose "$($ExportZipFileName).zip was created in $($DestinationPath)" }#IF } #Process END { Switch($Verify.IsPresent){ True{ Write-Verbose "File Verification switch detected" $ArchiveVerifyPath = ($DestinationPath + ($SourcePath | Split-Path -NoQualifier)) if($Recurse.IsPresent) { $FilesInArchive = Get-ChildItem $ArchiveVerifyPath\* -Include $FileType -Recurse }#IF else { $FilesInArchive = Get-ChildItem $ArchiveVerifyPath\* -Include $FileType }#Else if($FilesToArchive.Count -eq $FilesInArchive.Count) { Write-Verbose "FILE VERIFICATION PASSED" Write-Verbose "Files in Archive = $($FilesInArchive.Count)" Write-Verbose "Files From Source = $($FilesToArchive.Count)" } Else { Write-Verbose "FILE VERIFICATION FAILED" Write-Verbose "Files in Archive = $($FilesInArchive.Count)" Write-Verbose "Files From Source = $($FilesToArchive.Count)" }#Else }#True False{ }#False } if(($ArchiveToZip.IsPresent) -and ($FilesToArchive.count -eq $FilesInArchive.Count)){ Write-Verbose "Removing folder $($ZipFilePath)" Remove-Item $ZipFilePath -Confirm:$False -Recurse -Force -ErrorAction Stop }#IF elseif($Force.IsPresent){ Write-Verbose "Removing folder $($ZipFilePath). -Force Switch detected" Remove-Item $ZipFilePath -Confirm:$False -Recurse -Force -ErrorAction Stop } else{ Write-Verbose "$($ZipFilePath) Removal Failed." } }#END }#Function # SIG # Begin signature block # MIIGzwYJKoZIhvcNAQcCoIIGwDCCBrwCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUpIuLOoDnM32Az1EqCxQzVq78 # cl2gggRHMIIEQzCCAiugAwIBAgIQIzTOQXJ+IapNzXoyKIWCRTANBgkqhkiG9w0B # AQsFADA9MR8wHQYDVQQLDBZGb3IgVGVzdCBQdXJwb3NlcyBPbmx5MRowGAYDVQQD # DBFDZXJ0UmVxIFRlc3QgUm9vdDAeFw0xNzEyMjgwMjE1MjFaFw0xODEyMjgwMjM1 # MjFaMBUxEzARBgNVBAMMClNlY3VyZUNlcnQwggEiMA0GCSqGSIb3DQEBAQUAA4IB # DwAwggEKAoIBAQDA7XUJkhK7ZVD0RtIZfu7BVL26XVM1+O3VkSOxO7r1xbdnKUpq # LdITVNRzNwF+4mXIMbUBRBtrPal+jUnoFA+3l4Rsd8j7y9of2ibXOxo0o5GEv5X3 # pkKaqHqbMP+D0Y0fnc8c0KWy9eirMg9wnK2Yw+7UDs2Rp1BK6ovUkaiuN0QUx/mM # BYZUdpXyWSbWNFpXzm1IoU3aTgP/HWRcigsqoO3kMupNX1Q74ERlnEljhfIKH/hZ # im6PlebuG4AHKRMGZJrfLU6izom3BYMNSVrmZsdbIPmFnMBB1J/0WyJfafph1SaZ # gw8l9UoKAGG4qaXCCWx2Pr+8jrQkyQb5gOkRAgMBAAGjZzBlMA4GA1UdDwEB/wQE # AwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAfBgNVHSMEGDAWgBRzd3Eotls4z8iG # vhvpcx4xX60FojAdBgNVHQ4EFgQUO4nHKKKGpJm0aJLk7KZW63DS4uswDQYJKoZI # hvcNAQELBQADggIBADmFZB2J9tiuwG3cpIdUDMr2gXIOCbfFAOBm5Si4VlVAM1JS # 4U8j37f9oySpK2lB9Kc4fRAOjKpcUBJCQGGBFNeuuiYBzgMOiDBLftnb6stHgq8H # F/9U3xdO62lEp3NHijUKkFgeO5WJA0kdP7sI7ZGErdisP18gz3+bb6TglQV2/PvY # LXjCt98+l1uKpi4U/NQwez0wStQ0SXORSD7/l5ZCjXdPxP6CsAAsJBwq7GD9ZXeB # vnLw9iBgBXVF1sgjiGar7Hx6ZCp4Lzdj7ydJaPSysBJC4MnM1yBv7MfFNUHKxxaD # 7eSb7WMZfB1oonqETnoUWDnrbnzA9vngeUQZ0noymEFmkTvTl4dZBfJkEoGs4zkV # 7pLFqS0gc4RIOz2OE5119wZAMz6nRr2r394tNpZ/6xhqCvTPsLep0eneejM2Fayk # AAepuJbOoWXtkTiIiNiRDxaLhAa9tXshByRutDXRm5Y07m/Fao0BlC0T8O1BzW+F # XAiqQRZgJNmwtz239ykfLBqZuvnJ7vJG5xVFs29RiYJ5B/4VfSzkf8Y+8cdSNV53 # QH0IorEgelRFHXxxH8TnW4PKEO5iFz2Kq+qZYaChc1k5F3FRJNl3n8T/uZV34DR5 # ybxER738cVOHzAI9cJinFGIfYTvDKABoVjlGKavgkhoaSFZGj6vplSMz+yE2MYIB # 8jCCAe4CAQEwUTA9MR8wHQYDVQQLDBZGb3IgVGVzdCBQdXJwb3NlcyBPbmx5MRow # GAYDVQQDDBFDZXJ0UmVxIFRlc3QgUm9vdAIQIzTOQXJ+IapNzXoyKIWCRTAJBgUr # DgMCGgUAoHgwGAYKKwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMx # DAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkq # hkiG9w0BCQQxFgQUUl3Kxpp0PpXKxID7xpdGNqDVUc4wDQYJKoZIhvcNAQEBBQAE # ggEAGvPMze6YxYvs9bC+QurwOZw/K/SxMJNwLrbjBsv3ZVFJdjGiXFP6yKCTebs7 # xlNEWfWIAyCnpxiKGeZZs7FM5UvaJRLifMHwQ4LY+tivsgJMtnY5EwUv7f5dRaRC # lnXFUzPPSkbzPMg2AxFBcF2KbGrMTDyPDgnXq8HImobbXWEgCMAbyhT2aBdSA5Km # 2fy9xjqfbdmn+zc/6KjHRfwyFpMZC+ecdVCIDl93neE9rjouWUcGA3OD91xGYM8Y # YOj1e0buNKJTXDtyWVNoeUlRNzbB24RsxXXr5/G940XTqBgiWxYHYjKEXOQdPWk1 # E4QAjlT9wLujqlm6iOYnPPGFDw== # SIG # End signature block |