Share this page : facebooktwitterlinkedinmailfacebooktwitterlinkedinmail

Module code:

 

Add below file to powershell as a module, then use below script to backup the VMs to a ftp server:

Function Add-VmBackup
{
 param(
 [String]$vm = $null, 
 [String]$backupLocation = $null, 
 [String]$ftpBackupServer = $null, 
 [Int32]$ftpBackupServerPort = 21, 
 [String]$ftpUsername = $null, 
 [String]$ftpPassword = $null, 
 [String]$ftpBackupPath = ""
 )

function Archive($sourcedir, $zipFileName )
 {
 Add-Type -Assembly System.IO.Compression.FileSystem;

$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal;

[System.IO.Compression.ZipFile]::CreateFromDirectory($sourcedir, $zipfilename, $compressionLevel, $false);
 }

function Ftp($filePath, $ftpServer, $ftpPort, $ftpUsername, $ftpPassword, $ftpPath, $destinationFileName)
 {
 $ftpPath = $ftpPath.Trim('/')
 $ftpFullPath = $ftpServer + ":" + $ftpPort + "/" + $ftpPath + "/"

$webClient = (new-object System.Net.WebClient);
 
 try
 {
 $webClient.Credentials = (new-object System.Net.NetworkCredential($ftpUsername, $ftpPassword))
 $webClient.UploadFile($ftpFullPath + $destinationFileName, "STOR", $filePath);
 }
 finally
 {
 if($webClient -ne $null ) { $webClient.Dispose() }
 }
 }

#local variables

$ftpBackupServer = $ftpBackupServer.ToLower()

if( -not $ftpBackupServer.StartsWith("ftp://") ) { $ftpBackupServer = "ftp://" + $ftpBackupServer.trim('/') }



set ftpBackupPath ("/" + $ftpBackupPath.Trim('/') + "/" + $vm);



set-location $backupLocation
 $backupDate = ([System.DateTime]::Now.ToString("yyyyMMdd"))
 $snapshotName = ("bu_" + $backupDate)

set snapshotArchiveFilePath ([System.IO.Path]::Combine($backupLocation, ($vm + "-" + $backupDate + ".zip")))

set backupLocation ([System.IO.Path]::Combine($backupLocation, $vm + "-" + $backupDate))

try
 {
 if( test-path $backupLocation ) { remove-item -recurse -force $backupLocation }

New-item $backupLocation -type Directory | out-null
 checkpoint-vm $vm -SnapshotName $snapshotName -Passthru | Export-VMSnapshot -path $backupLocation
 
 if( test-path $snapshotArchiveFilePath ) { del $snapshotArchiveFilePath }

Archive $backupLocation $snapshotArchiveFilePath

remove-item -Recurse -Force $backupLocation

Ftp $snapshotArchiveFilePath $ftpBackupServer $ftpBackupServerPort $ftpUsername $ftpPassword $ftpBackupPath ($backupDate + ".zip")

remove-item $snapshotArchiveFilePath

Get-VMSnapshot -vmname $vm | where {$_.Name -like "bu_*" -and $_.creationTime -lt ([System.DateTime]::Today).Subtract((new-object System.TimeSpan(7, 0, 0, 0)))} | Remove-VMSnapshot
 }
 catch
 {
 echo $_.Exception.Message;
 # handle error here
 }

}

Use below code to


##don't change this script, it is been tested working perfectly!!!###
#change the vm names in the line 4, the script will loop in the order

$vms="vm1","vm2"
#shutdown service-desk
#shutdown smtp-relay
#shutdown confluence
#shutdown jira
#shutdown database

$continueLoop = $true

#$stoppedVm = @{}

foreach ($vm in $vms)
{
    try
    {
        if( $continueLoop ) 
        {
        stop-vm $vm 
        $continueLoop = !$LASTEXITCODE 
        #$stoppedVm += $vm
        }  
    }
    catch
    {    
        throw $_
    }
}

# backup smtp-relay first then start it
#try
#{
#    stop-vm smtp-relay

#    Add-VmBackup -vm smtp-relay -backupLocation C:\tmp\VMs -ftpBackupServer "ftp://path.to.your.ftp.server" -ftpUsername hypervbackup -ftpPassword your password -ftpBackupPath '/machines/'
#}
#catch
#{
#}
#finally
#{
#    start-vm smtp-relay
#}

#Then we do the following
#backup database
#backup jira
#backup confluence
#backup service desk

#start database
#start jira
#start confluence
#start service desk


#reverse the array
[array]::Reverse($vms)

##strat all the VMs

$continueLoop = $true

foreach ($vm in $vms)
{
    try
    {
        if( $continueLoop )
        {
            Add-VmBackup -vm $vm -backupLocation C:\tmp\VMs -ftpBackupServer "ftp://path.to.your.ftp.server" -ftpUsername hypervbackup -ftpPassword your password -ftpBackupPath '/machines/'
            start-vm $vm
            $continueLoop = !$LASTEXITCODE
        }
    }
    catch
    {
        throw $_
    }
}