PowerShell Get registry value data for backups
Scenario:
PowerShell Get registry value data for backups.
I have created this script for a specific reason. The reason is to avoid losing data and make sure that all data is included in the process of backups. Be aware that the script you will read below does not check data integrity of backups and health check. It only ensures you that all drives from each server will be included in the process during backup. When you are using VSS for backups a specific value in Windows registry can bring you a nightmare. There is a value in registry called DrivesToExclude that when you are backing up your Hyper-V Virtual Machines with VSS, it excludes those drives from backups. The value is under “HKLM:SYSTEM\CurrentControlSet\Control\BackupRestore\FilesNotToSnapshot“. In general the script retrieves data from the registry everyday and informs you for any wrong configuration on a server.
Let’s go in more detail on what it is going on in the script.
Firstly the script retrieves from Active Directory all computer objects under the servers organizational unit and saves the DNS names for those servers in a variable. Next you will see a function, which checks if the value exists or not and returns a true or false value. In the function I declare the path in registry and the key to check within the function. If the function will return true, then the script will retrieve that actual data of the registry key, by connecting to the specific server, that is used later to send it on email report. Please note here that, as I am also checking the server that the script is running on, I use a different command to check the specific server. If you use the same command as the other servers you will receive an error. Invoke-command is only used on remote servers and cannot be applied on this one.
At the end, if the specific registry key exists on a server and the script retrieved the actual key data on the server, an HTML email report is prepared. The HTML email report is send only if there is a server with the specific key configured. If nothing is found on the servers, no email will be sent. The table in the report includes the DNS name of the server, the value that the function returns, which is true or false and the actual registry key data. At the end of the script an error report is sent if there are any errors or exceptions while the script run. The error report is an HTML email with all values of the array of the default error variable. When the email is compiled, it will be sent and you will know if there was an error or exception thrown during the run.
You can download the script here or copy it from below.
Let me know your thoughts. You can comment below.
Related Links:
- Encrypt password with key using PowerShell
- Send Email using PowerShell
- Email error variable in PowerShell
- Get-Content – Microsoft Docs
- ConvertTo-SecureString – Microsoft Docs
- New-Object – Microsoft Docs
- Get-ADComputer – TechNet – Microsoft
- about_Functions | Microsoft Docs
- about_Try_Catch_Finally | Microsoft Docs
- Get-ItemProperty – Microsoft Docs
- Select-Object – Microsoft Docs
- Out-Null – Microsoft Docs
- Invoke-Command – Microsoft Docs
- Send-MailMessage – Microsoft Docs
Solution / Script:
$File = "C:\Scripts\Password.txt"
$Key = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32)
$EmailUser = "Script-User@domain.com"
$Password = Get-Content $File | ConvertTo-SecureString -Key $Key
$EmailCredentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $EmailUser,$Password
$To = 'User1@domain.com'
$From = 'Script-User@domain.com'
$EmailResult = ""
$hostnames = (Get-ADComputer -Filter * -SearchBase "OU=Servers,DC=domain,DC=com").DNSHostName
function Test-RegistryValue {
$Path = "HKLM:SYSTEM\CurrentControlSet\Control\BackupRestore\FilesNotToSnapshot"
$Value = "DrivesToExclude"
try {
Get-ItemProperty -Path $Path | Select-Object -ExpandProperty $Value -ErrorAction Stop | Out-Null
return $true
}
catch { return $false }
}
Foreach ($hostname in $hostnames) {
if ($hostname -eq "script-holding-server.domain.com") {
$RegistryValue = Test-RegistryValue
}
else {
$RegistryValue = Invoke-Command -ComputerName $hostname -Credential $EmailCredentials -ScriptBlock ${Function:Test-RegistryValue}
}
if ($RegistryValue -eq $true) {
$KeyValue = Invoke-Command -ComputerName $hostname -Credential $EmailCredentials -ScriptBlock {
$Path = "HKLM:SYSTEM\CurrentControlSet\Control\BackupRestore\FilesNotToSnapshot"
$Value = "DrivesToExclude"
(Get-ItemProperty -Path $Path -Name $Value).DrivesToExclude}
$EmailTemp = @"
<tr>
<td class="colorm">$hostname</td>
<td>$RegistryValue</td>
<td>$KeyValue</td>
</tr>
"@
$EmailResult = $EmailResult + "`r`n" + $EmailTemp
}
elseif ($RegistryValue -eq $null) {
$KeyValue = $null
$EmailTemp = @"
<tr>
<td class="colorm">$hostname</td>
<td>$RegistryValue</td>
<td>$KeyValue</td>
</tr>
"@
$EmailResult = $EmailResult + "`r`n" + $EmailTemp
}
}
$EmailUp = @"
<style>
body { font-family:Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif !important; color:#434242;}
TABLE { font-family:Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif !important; border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TR {border-width: 1px;padding: 10px;border-style: solid;border-color: white; }
TD {font-family:Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif !important; border-width: 1px;padding: 10px;border-style: solid;border-color: white; background-color:#C3DDDB;}
.colorm {background-color:#58A09E; color:white;}
.colort{background-color:#58A09E; padding:20px; color:white; font-weight:bold;}
.colorn{background-color:transparent;}
</style>
<body>
<h3>Script has been completed successfully</h3>
<h4>Registry has been found on the below Servers</h4>
<table>
<tr>
<td class="colort">Server Name</td>
<td class="colort">Registry Exist</td>
<td class="colort">Registry Value</td>
</tr>
"@
$EmailDown = @"
</table>
</body>
"@
$Email = $EmailUp + $EmailResult + $EmailDown
if ($EmailResult -ne "") {
send-mailmessage `
-To $To `
-Subject "Registry Value for backup Report $(Get-Date -format dd/MM/yyyy)" `
-Body $Email `
-BodyAsHtml `
-Priority high `
-UseSsl `
-Port 587 `
-SmtpServer 'smtp.office365.com' `
-From $From `
-Credential $EmailCredentials
}
if ($error -ne $null) {
foreach ($value in $error) {
$ErrorEmailTemp = @"
<tr>
<td class="colorm">$value</td>
</tr>
"@
$ErrorEmailResult = $ErrorEmailResult + "`r`n" + $ErrorEmailTemp
}
$ErrorEmailUp = @"
<style>
body { font-family:Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif !important; color:#434242;}
TABLE { font-family:Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif !important; border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TR {border-width: 1px;padding: 10px;border-style: solid;border-color: white; }
TD {font-family:Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif !important; border-width: 1px;padding: 10px;border-style: solid;border-color: white; background-color:#C3DDDB;}
.colorm {background-color:#58A09E; color:white;}
.colort{background-color:#58A09E; padding:20px; color:white; font-weight:bold;}
.colorn{background-color:transparent;}
</style>
<body>
<h3 style="color:#BD3337 !important;"> WARNING!!!</h3>
<p>There were errors during registry value check</p>
<p>Please check the errors and act accordingly</p>
<table>
"@
$ErrorEmailDown = @"
</table>
</body>
"@
$ErrorEmail = $ErrorEmailUp + $ErrorEmailResult + $ErrorEmailDown
send-mailmessage `
-To $To `
-Subject "Registry Value for backup Report $(Get-Date -format dd/MM/yyyy) - WARNING" `
-Body $ErrorEmail `
-BodyAsHtml `
-Priority high `
-UseSsl `
-Port 587 `
-SmtpServer 'smtp.office365.com' `
-From $From `
-Credential $EmailCredentials
}
Leave a Reply