Powershell is a great way to automate your daily tasks.As IT Pro has a lot of tasks that must complete daily and more tasks to schedule it for next day , next month or repeat a tasks every month.
The necessary of automation it's important for every IT Pro. Sometimes the difficult is to find the time and the concentration that need to create a Powershell Script , do the necessary tests to automate one of your tasks.
After several weeks i would like to publish a new Powershell script that create to automate one of my task.
The reason that create the Powershell script was because every month i must copy-paste files from 3 Servers in one of my NAS , compare it if the source-destination has the same size , delete the files from the source and keep the date which transfer the files.
This tasks there should be done after working hours to avoid performance issues in the specific servers.
So let's start !!
Before start to explain the Powershell script i would like to explain which are the steps that do every month before create the script.
- Stop the specific Service.
- Copy-Paste folders/files from the Server to a NAS which need credentials to login
- After finish the transfer compare the source and the destination if has the same size
- Delete all the files from the Source
- Start the Service
Base on these tasks i create the following Script.
Stop-Service <servicename>
$password = convertto-securestring -String <password> -AsPlainText -Force
$mycred = new-object -typename System.Management.Automation.PSCredential('<username>', $password)
New-PSDrive -Name w -PSProvider FileSystem -Root <Destinatiton Folder> -Credential $mycred
$logProgress = 'c:\copyLogs.txt'
Copy-Item "<Source folder>" -Destination "w:\$((Get-Date).ToString('yyyy-MM-dd'))" -recurse -ErrorAction SilentlyContinue -ErrorVariable copy_log
if($copy_log) {write-output "Copy Failed at " "$([DateTime]::Now)" | Out-File -Append $logProgress}
else {write-output "Copy Finish Successfull at" "$([DateTime]::Now)" | Out-File -Append $logProgress}
$var1=Get-ChildItem "<Source Folder>" -Recurse | Measure-Object -sum Length
$var2=Get-ChildItem "w:\$((Get-Date).ToString('yyyy-MM-dd'))" -Recurse | Measure-Object -sum Length
$var3=$var1.sum
$var4=$var2.sum
Remove-PSDRive -name w
if ($var3 -eq $var4)
{
Remove-Item "<Source Folder>" -Recurse -ErrorAction SilentlyContinue -ErrorVariable copy_log
write-output "Delete Succes at" "$([DateTime]::Now)" | Out-File -Append $logProgress
Start-Service <service name>
}
Else
{ write-output "Delete Failed because Size between source and Destination it's not the same at" "$([DateTime]::Now)" | Out-File -Append $logProgress }
---------------------------------------------------------------
If you want you can download from here
So let's start to explain step by step what i have done in the script.
Step 1 : Stop the specific Service
First step is to stop the Service.
Stop-Service <servicename>
Step 2 : Connect to NAS (Destination Folder)
Because my NAS has username and password must give it in the Script to open the Destination Folder. So in Powershell convert the password to securestring and save it in variable
$password = convertto-securestring -String <password> -AsPlainText -Force
Because we have store the password in securestring use the PSCredential Class to retrieve username and password.
$mycred = new-object -typename System.Management.Automation.PSCredential('<username>', $password)
The destination folder is UNC Path. So with PSDrive create a temporary map drive in the destination folder and give the Credentials from $mycred
New-PSDrive -Name w -PSProvider FileSystem -Root <Destinatiton Folder> -Credential $mycred
Very important to create a file which log what happened. So you would know if the transfer complete or not
Step 3: Create Log File
$logProgress = 'c:\copyLogs.txt'
Step 3 :Copy Folder
With Copy-Item start the Copy from Source Folder to the Destination. As you can see the Destination is w:\$((Get-Date).ToString('yyyy-MM-dd')). The w is the Name of the Map Drive that give in PsDrive when created. The $((Get-Date).ToString('yyyy-MM-dd') will be create a folder with the date of the copy. Also use ErrorAction and ErrorVariable for error handling
Copy-Item "<Source folder>" -Destination "w:\$((Get-Date).ToString('yyyy-MM-dd'))" -recurse -ErrorAction SilentlyContinue -ErrorVariable copy_log
Use if statement to identify what must be write in the log file. You can use whatever you want . In y case i use only Copy Failed or Copy Success
if($copy_log) {write-output "Copy Failed at " "$([DateTime]::Now)" | Out-File -Append $logProgress}
else {write-output "Copy Finish Successfull at" "$([DateTime]::Now)" | Out-File -Append $logProgress}
Step 4 : Compare Size of Different Folders and act base on Results.
But because after finish the copy i must compare the Folder Sizes between source and destination save the Length of the folders in variable
$var1=Get-ChildItem "<Source Folder>" -Recurse | Measure-Object -sum Length
$var2=Get-ChildItem "w:\$((Get-Date).ToString('yyyy-MM-dd'))" -Recurse | Measure-Object -sum Length
To be able to do the comparison i use only the sum which is the number of the size in bytes in another variable
$var3=$var1.sum
$var4=$var2.sum
Remove the temporary mapdrive
Remove-PSDRive -name w
Do the comparison between the 2 folders and with the if statement decide what must be done. If the folders are equal then will be delete the source folder and Start the Service that must be started. Else just will write in log file file without do anything.
if ($var3 -eq $var4)
{
Remove-Item "<Source Folder>" -Recurse -ErrorAction SilentlyContinue -ErrorVariable copy_log
write-output "Delete Succes at" "$([DateTime]::Now)" | Out-File -Append $logProgress
Start-Service <service name>
}
Else
{ write-output "Delete Failed because Size between source and Destination it's not the same at" "$([DateTime]::Now)" | Out-File -Append $logProgress }