#Script must be executed as Admin... # it will stop virtual machines and docker-desktop, copy files to e:\backup\ and restart the services... $VMs = @{} Import-Module BitsTransfer function shutdownHyperV(){ $machines = Get-VM foreach ($m in $machines) { if ($m.State -eq "Running") { Write-Host "Shutting down:"($m.Name) $VMs[($m.Name)]=$m Stop-VM -Name ($m.Name) } } } function restartHyperV(){ foreach ($m in $VMs.Keys){ Write-Host "Starting VM:"($m) Start-VM -Name $m } } function stopDocker(){ Write-Output "Stopping docker..." foreach($svc in (Get-Service | Where-Object {$_.name -ilike "*docker*" -and $_.Status -ieq "Running"})) { $svc | Stop-Service -ErrorAction Continue -Confirm:$false -Force $svc.WaitForStatus('Stopped','00:00:20') } Get-Process | Where-Object {$_.Name -ilike "*docker*"} | Stop-Process -ErrorAction Continue -Confirm:$false -Force foreach($svc in (Get-Service | Where-Object {$_.name -ilike "*docker*" -and $_.Status -ieq "Stopped"} )) { $svc | Start-Service $svc.WaitForStatus('Running','00:00:20') } } function startDocker(){ Write-Output "Starting docker..." & "C:\Program Files\Docker\Docker\Docker Desktop.exe" $startTimeout = [DateTime]::Now.AddSeconds(90) $timeoutHit = $true while ((Get-Date) -le $startTimeout) { Start-Sleep -Seconds 10 $ErrorActionPreference = 'Continue' try { $info = (docker info) Write-Verbose "$((Get-Date).ToString("HH:mm:ss")) - `tDocker info executed. Is Error?: $($info -ilike "*error*"). Result was: $info" if ($info -ilike "*error*") { Write-Verbose "$((Get-Date).ToString("HH:mm:ss")) - `tDocker info had an error. throwing..." throw "Error running info command $info" } $timeoutHit = $false break } catch { if (($_ -ilike "*error during connect*") -or ($_ -ilike "*errors pretty printing info*") -or ($_ -ilike "*Error running info command*")) { Write-Output "$((Get-Date).ToString("HH:mm:ss")) -`t Docker Desktop startup not yet completed, waiting and checking again" } else { Write-Output "Unexpected Error: `n $_" return } } $ErrorActionPreference = 'Stop' } if ($timeoutHit -eq $true) { throw "Timeout hit waiting for docker to startup" } } function copyDir($Source,$Destination){ Write-Host("Copy Folder: $Source to Folder: $Destination") $files = Get-ChildItem $Source -Recurse foreach ($f in $files){ $dest = $f.FullName.Replace($Source,$Destination) if ($f.PSIsContainer){ $n = New-Item -ItemType Directory -Force -Path $dest } else { if ($f.Length -gt 10000000){ #Start-BitsTransfer -Source $f.FullName -Destination $dest } else { #Copy-Item -Path $f.FullName -Destination $dest } } } } function copyFiles(){ $d = (Get-Date -format "yyyy-MM-dd").ToString() $Destination = "E:\Backup\"+$d $out = New-Item -ItemType Directory -Force -Path $Destination $Source = "D:\Hyper-V" $Dest = $Destination+"\Hyper-V" copyDir -Source $Source -Destination $Dest $Source = "D:\docker-desktop" $Dest = $Destination+"\docker-desktop" copyDir -Source $Source -Destination $Dest } #Main... Write-Host "Starting Backup script..." $s = Get-Date shutdownHyperV stopDocker copyFiles restartHyperV startDocker Write-Host "All done..." $e = Get-Date $Runtime = New-TimeSpan -Start $s -End $e Write-Host "...in "+$Runtime