You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
First of all let me say i really like you're way of scripting and love to see your enthusiasm in your work.
Last year i've made my own version of you script then because i needed to be more lightweight and there were a few things not available then like the -LowDisk switch. But today i've check what you've been working at and i'm impressed, it almost fits my need and i know it's a lot to ask (since i can do it myself) but could you consider to add these features?
Switch called -SendStatusUpdate: this features send after every VM a email with the status of that VM export. For example, in my case i have a few VM's that are TB's and the script runs at night. When it's morning i can see due to the emails where the backup script is in the process. I simply put a SendEmail at the end of the ForEach VM (Check second code block below)
Switch calles -OptimizeVHD: this features uses the Optimize-VHD function before copying it to the backup destination. Example of the code i use inside the ForEach VM:
#Optimze the VHDXTry {
Write-Log-Type Info -Evt "Optimizing VHD(s)..."$VMVHDS=Get-VHD-Path $($Vm|Get-VMHardDiskDrive|Select-Object-ExpandProperty "Path")
#Loop through each VHD(X) file of an VM an optimize itForEach ($VHDin$VMVHDS) {
#Now optimize the VHD to save space and therefore shorten the copy timeWrite-Log-Type Info -Evt "Used space before optimizing VHD [$($VHD.Path)] = $([math]::ceiling((Get-VHD-Path $VHD.Path).FileSize /1GB )) GB"Optimize-VHD-Path "$($VHD.Path)"-Mode Full
Write-Log-Type Info -Evt "Used space after optimizing VHD [$($VHD.Path)] = $([math]::ceiling((Get-VHD-Path $VHD.Path).FileSize /1GB )) GB"$intTotalDisksSize+= (Get-VHD-Path $VHD.Path).FileSize
}
Write-Log-Type Info -Evt "Done optimizing VHD(s)"
}
Catch {
Write-Log-Type Err -Evt "Error during Optimize-VHD: $($_.Exception.Message)"
}
Print the duration of how long it took per VM to back. In my script i simply compare time from the beginning of the ForEach VM and in one of the last lines print the duration. This gives me a pretty good idea how long it takes per VM.
For example:
Write-Log-Type Info ""Write-Log-Type Info "-------------------------- Processing VM: $Vm --------------------------------"$StartTime=$(get-date)
...do stuff ...
$elapsedTime=$(get-date) -$StartTime$totalTime="{0:HH:mm:ss}"-f ([datetime]$elapsedTime.Ticks)
SendMail "VM $Vm done""Processed VM: $Vm in $totalTime"Write-Log-Type Info "-------------------------- Done processing VM: $Vm in $totalTime --------------------------------"Write-Log-Type Info ""
Switch -PrintVMInfo: this features simply printout all info it could find. For example what i use:
## Print info per VM.ForEach ($Vmin$Vms) {
#Get SystemInfoTry {
#Log VM specs$VhdSize=Get-VHD-Path $($Vm|Get-VMHardDiskDrive|Select-Object-ExpandProperty "Path") |Select-Object@{Name="FileSizeGB"; Expression= { [math]::ceiling( $_.FileSize/1GB ) } },@{Name="M Write-Output "VM [$Vm] has [$((Get-VMProcessor$Vm).Count)] CPU cores, [$([math]::ceiling((Get-VMMemory$Vm).Startup /1gb))GB] RAM and Storage [CurrentFileSizeGB=$($VhdSize.FileSizeGB)GB-MaxSizeG
}
Catch {
Write-Error"Error during Systeminfo: $($_.Exception.Message)"
}
}
Extra funtions start Start and Stop a backupserver. This is something i have in my script because when the backuopserver isn't needed it is shutdown. (For security and power reasons). Snippit of the code:
functionInvoke-WakeOnLan {
param
(
# one or more MACAddresses
[Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
# mac address must be a following this regex pattern:
[ValidatePattern('^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$')]
[string[]]
$MacAddress
)
begin {
# instantiate a UDP client:# Support from PowerShell V5.X $UDPclient = [System.Net.Sockets.UdpClient]::new()$UDPclient=New-Object-TypeName System.Net.Sockets.UdpClient
}
process {
foreach ($_in$MacAddress) {
try {
$currentMacAddress=$_# get byte array from mac address:$mac=$currentMacAddress-split'[:-]'|# convert the hex number into byte:ForEach-Object {
[System.Convert]::ToByte($_,16)
}
#region compose the "magic packet"# create a byte array with 102 bytes initialized to 255 each:$packet= [byte[]](,0xFF*102)
# leave the first 6 bytes untouched, and# repeat the target mac address bytes in bytes 7 through 102:6..101|Foreach-Object {
# $_ is indexing in the byte array,# $_ % 6 produces repeating indices between 0 and 5# (modulo operator)$packet[$_] =$mac[($_%6)]
}
#endregion# connect to port 400 on broadcast address:$UDPclient.Connect(([System.Net.IPAddress]::Broadcast),4000)
# send the magic packet to the broadcast address:$null=$UDPclient.Send($packet,$packet.Length)
Write-Log-Type Info -Evt "Sent magic packet to $currentMacAddress..."
}
catch {
Write-Log-Type Err -Evt "Unable to send ${mac}: $_"
}
}
}
end {
# release the UDF client and free its memory:$UDPclient.Close()
$UDPclient.Dispose()
}
}
... later on ...
# Let's start the BackupServer if it's not runningIf (Test-Connection-ComputerName "IP/Hostname"-Count 2-Delay 5-Quiet ) {
#Backup server responded meaning it's already online.Write-Log-Type Info -Evt "BackupServer is online, waiting 30 seconds just to be sure..."Start-Sleep30
}
else {
Write-Log-Type Info -Evt "Sending magic packet to BackupServer [$BackupServerMacAddress]"Invoke-WakeOnLan-MacAddress "$BackupServerMacAddress"-Verbose
#Now wait until backupserver is onlineWrite-Log-Type Info -Evt "Waiting for BackupServer to come online..."If (Test-Connection-ComputerName "IP/Hostname"-Count 12-Delay 10-Quiet ) {
#Backupserver responded now give some extra time for Windows to fully be up and runningWrite-Log-Type Info -Evt "BackupServer is online, waiting 2 more minutes for Windows to complete..."Start-Sleep120
}
else {
Write-Log-Type Err -Evt "Backupserver failed to respond within 2 minutes. BACkUP SCRIPT WILL NOT CONTINUE"$MailBody=Get-Content-Path $Log|Out-String
SendMail "VM Backup: Failed to start backupserver"$MailBodyWrite-Log-Type Info -Evt "Log finished"Exit
}
}
... When done, shutdown ...
## Now shutdown the backup serverTry {
Write-Log-Type Info -Evt "Waiting for BackupServer to shutdown..."Stop-Computer-ComputerName "IP/Hostname"-Credential $credObject-Force
#Wait until backupserver is downWhile ( Test-Connection"IP/Hostname"-Quiet -Count 1) {
Start-Sleep-Seconds 10#Check if we are waiting more than two minutesif ($timer.Elapsed.TotalSeconds-gt120) {
Write-Log-Type Err -Evt "Backupserver shutdown did not complete before timeout period."Break
}
}
#Double check if server is down or Watchdog has kicked inif (-Not (Test-Connection"IP/Hostname"-Quiet -Count 2)) {
Write-Log-Type Info -Evt "BackupServer succesfully shutdown"
}
}
catch {
Write-Log-Type Err -Evt "Error backup shutdown: $($_.Exception.Message)"
}
Those are the points i have, not to bad right ;-)
Again, thanks for all your effort so far!
The text was updated successfully, but these errors were encountered:
I'm adding all the suggestions here except for the Wake On Lan option for the time being. WOL feels a little out of scope but I'm willing to add it if there's a demand.
First of all let me say i really like you're way of scripting and love to see your enthusiasm in your work.
Last year i've made my own version of you script then because i needed to be more lightweight and there were a few things not available then like the
-LowDisk
switch. But today i've check what you've been working at and i'm impressed, it almost fits my need and i know it's a lot to ask (since i can do it myself) but could you consider to add these features?-SendStatusUpdate
: this features send after every VM a email with the status of that VM export. For example, in my case i have a few VM's that are TB's and the script runs at night. When it's morning i can see due to the emails where the backup script is in the process. I simply put aSendEmail
at the end of theForEach VM
(Check second code block below)-OptimizeVHD
: this features uses theOptimize-VHD
function before copying it to the backup destination. Example of the code i use inside theForEach VM
:ForEach VM
and in one of the last lines print the duration. This gives me a pretty good idea how long it takes per VM.For example:
Those are the points i have, not to bad right ;-)
Again, thanks for all your effort so far!
The text was updated successfully, but these errors were encountered: