我想使用Veeam的免费版本在Windows Hyper-V 2016服务器上备份我的虚拟机。该工具的免费版本不提供定期备份的工具,因此我一直在研究将其API与任务调度程序结合使用的方法。
在我寻找解决方案时,我遇到了这篇文章,其中详细介绍了我需要的所有内容:
https://blog.mwpreston.net/2015/04/29/scheduling-veeam-backup-free-edition-backups/
Param(
[Parameter(Mandatory=$true)][string]$VM,
[Parameter(Mandatory=$true)][string]$Destination,
[Parameter(Mandatory=$true)][ValidateSet(0,4,5,6,9)][int]$Compression,
[bool]$DisableQuiesce=$true,
[Parameter(Mandatory=$true)][ValidateSet("Never","Tonight","TomorrowNight","In3days","In1Week","In2Weeks","In1Month")][string]$Autodelete
)
#Load Veeam Toolkit
& "C:\Program Files\Veeam\Backup and Replication\Backup\Initialize-VeeamToolkit.ps1"
#Validate any parameters
$vmentity = Find-VBRViEntity -Name $VM
if ($vmentity -eq $null)
{
Write-Host "VM: $VM not found" -ForegroundColor "red"
exit
}
if (-Not (Test-Path $Destination))
{
Write-Host "Destination: $vmname not valid" -ForegroundColor "red"
exit
}
if ($DisableQuiesce -eq $true)
{
Start-VBRZip -Entity $vmentity -Folder $destination -Compression $Compression -AutoDelete $Autodelete -DisableQuiesce
}
else
{
Start-VBRZip -Entity $vmentity -Folder $destination -Compression $Compression -AutoDelete $Autodelete
}
但是,此页面上的sript仅支持备份单个VM。我可以创建许多这样的脚本,但是使用一个循环通过VM的脚本将是首选。
我认为这就像循环遍历所有虚拟机一样简单,但由于我没有使用PowerShell脚本,也没有使用Veeam,我正在寻找一些帮助/协助来修改脚本以备份所有虚拟机。在该页面的评论中有一些关于此的讨论,但是博客文章似乎已经更新,因此它不直接适用。
例如:
(get-vm -ComputerName YOURSERVERFQDN | foreach { $_.Name }) -join "`",`"" | Tee-Object -Variable VMNames | Out-Null
奖金会在失败时添加某种电子邮件通知,但这有点超出了这个问题的主题。
答案 0 :(得分:0)
复活一个老问题,但是显然Q有很多观点,所以我认为我应该分享自己使用过的脚本的最终版本。这是基于我在某处找到的原始脚本的不同版本,并针对我的目的进行了修改。
它不是很优雅,但是可以完成工作,如果失败,它会通过电子邮件发送一些方便的错误消息。
Param(
[Parameter(Mandatory=$false)][string]$hostname = 'yourhostname',
[Parameter(Mandatory=$false)][string]$BackupDestination = '\\yourdestination',
[ValidateSet(0,4,5,6,9)][int]$CompressionLevel = 5,
[bool]$DisableQuiesce=$false,
[ValidateSet("Never","Tonight","TomorrowNight","In3days","In1Week","In2Weeks","In1Month")][string]$Autodelete = "Tonight",
[bool]$EnableNotification=$true,
[string]$SMTPServer = 'smpt.yourmailserver.com'
)
##################################################################
# Notification Settings
##################################################################
# Email FROM
$EmailFrom = "veeam@domain"
# Email TO
$EmailTo = "you@domain"
# Email subject
$EmailSubject = "Veeam backup failed!"
##################################################################
# Email formatting
##################################################################
$style = "<style>BODY{font-family: Arial; font-size: 10pt;}"
$style = $style + "TABLE{border: 1px solid black; border-collapse: collapse;}"
$style = $style + "TH{border: 1px solid black; background: #dddddd; padding: 5px; }"
$style = $style + "TD{border: 1px solid black; padding: 5px; }"
$style = $style + "</style>"
try{
#Load Veeam Toolkit
& "C:\Program Files\Veeam\Backup and Replication\Console\Initialize-VeeamToolkit.ps1"
#Gather VM list dynamically
#Different methods of getting the vmlist
#$Script:VMList= (Get-VM -ComputerName $hostname -Credential $currentUser)
$script:VMList = Find-VBRHvEntity | Where-Object {$_.Type -eq 'Vm' -and $_.PowerState -eq "PoweredOn"}
#Add the hostname to the path in case you use some generic path
#$BackupDestinationWithHostName = Join-Path $BackupDestination $hostname
#Get the NAS credentials. This may not be needed depending on your setup. I am using active directy, but still found this to be the least painful solution
$NASCredentials = Get-VBRCredentials -Name "veeam@domain"
#Perform backup task for each identified VM
foreach ($vmentity in $VMList) {
#Perform the actual backup
$ZIPSession = Start-VBRZip -NetworkCredentials $NASCredentials -Entity $vmentity -Folder $BackupDestination -Compression $CompressionLevel -DisableQuiesce:($DisableQuiesce) -AutoDelete $Autodelete
#$ZIPSession = Start-VBRZip -Entity $vmentity -Folder $BackupDestination -Compression $CompressionLevel -DisableQuiesce:($DisableQuiesce) -AutoDelete $Autodelete
$TaskSessions = $ZIPSession.GetTaskSessions().logger.getlog().updatedrecords
$FailedSessions = $TaskSessions | where {$_.status -eq "EWarning" -or $_.Status -eq "EFailed"}
If ($EnableNotification) {
if ($FailedSessions -ne $Null) {
$sendFailedEmail = $true
$thisMessage = ($ZIPSession | Select-Object @{n="Name";e={($_.name).Substring(0, $_.name.LastIndexOf("("))}} ,@{n="Start Time";e={$_.CreationTime}},@{n="End Time";e={$_.EndTime}},Result,@{n="Details";e={$FailedSessions.Title}})
$MessageBody += $thisMessage
}
}
}
If (($EnableNotification -eq $true) -and ($sendFailedEmail -eq $true)) {
$Message = New-Object System.Net.Mail.MailMessage $EmailFrom, $EmailTo
$Message.Subject = $EmailSubject
$Message.IsBodyHTML = $True
$message.Body = $MessageBody | ConvertTo-Html -head $style | Out-String
$SMTP = New-Object Net.Mail.SmtpClient($SMTPServer)
$SMTP.Send($Message)
}
} catch{
$ErrorMessage = $_.Exception.Message
$Message = New-Object System.Net.Mail.MailMessage $EmailFrom, $EmailTo
$Message.Subject = "Unexpected error in Veeam powershell script"
$Message.Body = $ErrorMessage
$SMTP = New-Object Net.Mail.SmtpClient($SMTPServer)
$SMTP.Send($Message)
echo $_.Exception.Message
} finally {
# Any cleanup you need to perform. I am shutting down the server as it restarts on an automatic cycle when the task has to run again.
Stop-Computer
}