-
- Service Provider
- Posts: 26
- Liked: 3 times
- Joined: Apr 19, 2017 3:47 pm
- Full Name: Ryan Faulkner
- Contact:
SureBackup and a Powershell script
Hello all,
I'm trying to setup a SureBackup job, with a backup protected Windows VM, where a script is added to the SureBackup job that will run chkdsk on the booted up SureBackup VM.
I'm confused about how I need to use the Arguments field within the Test Scripts window along with the selected ps1 script. Do I have to make the powershell script itself connect to the Veeam Lab VM itself? I assume the ps1 script will have to have lines for connecting to a remote Server using %vm_ip% or $server = "%vm_ip% this is the part I'm confused about, how do I get the script in the job and the ps1 script connecting to the powered up SureBackup VM?
I've been looking in https://github.com/VeeamHub/powershell/tree/master and reading this script https://github.com/VeeamHub/powershell/ ... etcred.ps1 where it appears where $server = "localhost" is used and within the SureBackup job arguments I think -server %vm_ip% is connected back to that localhost in the script?
Any help at all is appreciated, thanks!
Ryan
I'm trying to setup a SureBackup job, with a backup protected Windows VM, where a script is added to the SureBackup job that will run chkdsk on the booted up SureBackup VM.
I'm confused about how I need to use the Arguments field within the Test Scripts window along with the selected ps1 script. Do I have to make the powershell script itself connect to the Veeam Lab VM itself? I assume the ps1 script will have to have lines for connecting to a remote Server using %vm_ip% or $server = "%vm_ip% this is the part I'm confused about, how do I get the script in the job and the ps1 script connecting to the powered up SureBackup VM?
I've been looking in https://github.com/VeeamHub/powershell/tree/master and reading this script https://github.com/VeeamHub/powershell/ ... etcred.ps1 where it appears where $server = "localhost" is used and within the SureBackup job arguments I think -server %vm_ip% is connected back to that localhost in the script?
Any help at all is appreciated, thanks!
Ryan
-
- Product Manager
- Posts: 15146
- Liked: 3242 times
- Joined: Sep 01, 2014 11:46 am
- Full Name: Hannes Kasparick
- Location: Austria
- Contact:
Re: SureBackup and a Powershell script
Hello,
yes, the script needs to connect to the VM. This thread has some examples for PowerShell
As far as I see, the example script from Github needs to be adjusted. The $server variable is set static and needs to be replaced by the server name / IP. I don't see any external parameter input in that script.
Best regards,
Hannes
yes, the script needs to connect to the VM. This thread has some examples for PowerShell
As far as I see, the example script from Github needs to be adjusted. The $server variable is set static and needs to be replaced by the server name / IP. I don't see any external parameter input in that script.
Best regards,
Hannes
-
- Service Provider
- Posts: 26
- Liked: 3 times
- Joined: Apr 19, 2017 3:47 pm
- Full Name: Ryan Faulkner
- Contact:
Re: SureBackup and a Powershell script
Hi Hannes,
Thank you for the reply. Can I tell the powershell script to use either the %vm_fqdn% or %vm_fqdn% or do I have to statically program in the ps script the IP address of the masquerade IP? Do you know of any example powershell scripts and SureBackup job settings that run powershell scripts on remote Servers?
Thanks,
Ryan
Thank you for the reply. Can I tell the powershell script to use either the %vm_fqdn% or %vm_fqdn% or do I have to statically program in the ps script the IP address of the masquerade IP? Do you know of any example powershell scripts and SureBackup job settings that run powershell scripts on remote Servers?
Thanks,
Ryan
-
- Service Provider
- Posts: 26
- Liked: 3 times
- Joined: Apr 19, 2017 3:47 pm
- Full Name: Ryan Faulkner
- Contact:
Re: SureBackup and a Powershell script
Hit a snag. Got a script working manually, but Veeam apparently can't connect to the CredentialManager without creds, defeats the purpose of not storing creds within my script.
snippet of task.application_group.log
[13.09.2023 11:50:28.686] <73> Info [SureBackup] [X] [ScriptTests] [Console] Get-StoredCredential : CredRead failed with the error code 1312.
[13.09.2023 11:50:28.687] <73> Info [SureBackup] [X] [ScriptTests] [Console] At C:\VeeamScript\VeeamScript1.ps1:10 char:12
[13.09.2023 11:50:28.687] <73> Info [SureBackup] [X] [ScriptTests] [Console] + $MyCreds = Get-StoredCredential -Target 'domainadmin'
[13.09.2023 11:50:28.687] <73> Info [SureBackup] [X] [ScriptTests] [Console] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[13.09.2023 11:50:28.687] <73> Info [SureBackup] [X] [ScriptTests] [Console] + CategoryInfo : InvalidOperation: (domainadmin:String) [Get-Stor
[13.09.2023 11:50:28.687] <73> Info [SureBackup] [X] [ScriptTests] [Console] edCredential], Exception
[13.09.2023 11:50:28.687] <73> Info [SureBackup] [X] [ScriptTests] [Console] + FullyQualifiedErrorId : 1,PSCredentialManager.Cmdlet.GetStoredCredential
[13.09.2023 11:50:28.687] <73> Info [SureBackup] [x] [ScriptTests] [Console]
[13.09.2023 11:50:28.690] <73> Info [SureBackup] [X] [ScriptTests] [Console] WARNING: Unable to convert Credential object without username or password to
[13.09.2023 11:50:28.690] <73> Info [SureBackup] [X] [ScriptTests] [Console] PSCredential object
Here is my actual ps script that's setup in the application group:
#input the target IP of the remote machine
$target = "192.168.255.203"
#get creds from CredentialManager
$MyCreds = Get-StoredCredential -Target 'domainadmin'
#run the script on the remote machine
Invoke-Command -ComputerName $target -FilePath c:\VeeamScript\chkdsk_test_editing-final.ps1 -credential $MyCreds
__________________
I had tried using a stored credential text file but Veeam/SureBackup couldn't read or find the file...
Not sure where to go from here.
snippet of task.application_group.log
[13.09.2023 11:50:28.686] <73> Info [SureBackup] [X] [ScriptTests] [Console] Get-StoredCredential : CredRead failed with the error code 1312.
[13.09.2023 11:50:28.687] <73> Info [SureBackup] [X] [ScriptTests] [Console] At C:\VeeamScript\VeeamScript1.ps1:10 char:12
[13.09.2023 11:50:28.687] <73> Info [SureBackup] [X] [ScriptTests] [Console] + $MyCreds = Get-StoredCredential -Target 'domainadmin'
[13.09.2023 11:50:28.687] <73> Info [SureBackup] [X] [ScriptTests] [Console] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[13.09.2023 11:50:28.687] <73> Info [SureBackup] [X] [ScriptTests] [Console] + CategoryInfo : InvalidOperation: (domainadmin:String) [Get-Stor
[13.09.2023 11:50:28.687] <73> Info [SureBackup] [X] [ScriptTests] [Console] edCredential], Exception
[13.09.2023 11:50:28.687] <73> Info [SureBackup] [X] [ScriptTests] [Console] + FullyQualifiedErrorId : 1,PSCredentialManager.Cmdlet.GetStoredCredential
[13.09.2023 11:50:28.687] <73> Info [SureBackup] [x] [ScriptTests] [Console]
[13.09.2023 11:50:28.690] <73> Info [SureBackup] [X] [ScriptTests] [Console] WARNING: Unable to convert Credential object without username or password to
[13.09.2023 11:50:28.690] <73> Info [SureBackup] [X] [ScriptTests] [Console] PSCredential object
Here is my actual ps script that's setup in the application group:
#input the target IP of the remote machine
$target = "192.168.255.203"
#get creds from CredentialManager
$MyCreds = Get-StoredCredential -Target 'domainadmin'
#run the script on the remote machine
Invoke-Command -ComputerName $target -FilePath c:\VeeamScript\chkdsk_test_editing-final.ps1 -credential $MyCreds
__________________
I had tried using a stored credential text file but Veeam/SureBackup couldn't read or find the file...
Not sure where to go from here.
-
- Veeam Software
- Posts: 1838
- Liked: 661 times
- Joined: Mar 02, 2012 1:40 pm
- Full Name: Timothy Dewin
- Contact:
Re: SureBackup and a Powershell script
It's a 6 year old script but param allows you to pass -server option. That is the idea. Also this uses netcred, eg basically it uses the credentials that you can set on the surebackup script configuration post433126.html
You don't need to extract the credentials yourself, it uses the netcreds by using this connection statement "Integrated Security=True;". Basically, surebackup starts up the script with the supplied credentials (set netcreds), and the script connects with the supplied credentials.
You don't need to extract the credentials yourself, it uses the netcreds by using this connection statement "Integrated Security=True;". Basically, surebackup starts up the script with the supplied credentials (set netcreds), and the script connects with the supplied credentials.
-
- Service Provider
- Posts: 26
- Liked: 3 times
- Joined: Apr 19, 2017 3:47 pm
- Full Name: Ryan Faulkner
- Contact:
Re: SureBackup and a Powershell script
The fine folks at Veeam support pointed me in the right direction, to this article: https://vnote42.net/2022/05/23/using-cu ... ment-17780
Couple of things to note:
#1 - under the 4. Write start script, the script must start with Param as shown, nothing can be in front or above it, otherwise Param won't be recognized
#2 - also under the 4. Write start script, the -ScriptBlock must be immediately followed by the { character, so not as they show where it's in a line below and has spaces in front.
I want to share this with everyone as it became useful to us, but here is the final chkdsk script and leading start, the chkdsk script checks all volumes on the booted up SureBackup Veeam Lab isolated Windows machine for ntfs integrity errors and if any are found a file is created and then the script exits 1 if that file is found, which is the error code that SureBackup will detect and use as indication of a failure so the job will show failed.
This gets added to the application group test scripts, using as the article above shows and adding the %vm_ip% to the Arguments. I also tested with a domain admin account and that failed as the VM doesn't have access to the domain and it doesn't appear to accept cached creds on the VM, so I used a local admin account on the VM.
I did not create the script after PHASE 1, other than adding in the changes I needed so it would exit and create a file if an error was found during chkdsk. I further plan to re-adapt this using Repair-Volume rather than chkdsk.
Create any name ps1 script with the data immediately below:
Param($TestVmIP)
$ReturnCode = 1
$CredObject = Import-Clixml -Path C:\VeeamScript\CredObject.xml
$ReturnCode = Invoke-Command -Credential $CredObject -Computername $TestVmIP -ErrorAction Stop -ScriptBlock{
### Start of script code
$ReturnFail = 1
$ReturnSuccess = 0
<#
PHASE 1: OPERATING SYSTEM INFO
#>
# Getting OS info and displaying it
Write-Output "Computer hostname is $env:computername"
$folderPath = "c:\temp"
if (!(Test-Path $folderPath -PathType Container)) {
New-Item -ItemType Directory -Force -Path $folderPath
}
New-Item en-CA.txt
New-Item en-US.txt
Add-Content en-US.txt ("8= Windows has scanned the file system and found no problems;No further action is required; 0 KB in bad sectors")
Add-Content en-US.txt ("7= Windows has checked the file system and found no problems; 0 KB in bad sectors")
Add-Content en-US.txt ("bad= bad sectors")
Add-Content en-CA.txt ("8= Windows has scanned the file system and found no problems;No further action is required; 0 KB in bad sectors")
Add-Content en-CA.txt ("7= Windows has checked the file system and found no problems; 0 KB in bad sectors")
Add-Content en-CA.txt ("bad= bad sectors")
$os_info = Get-WmiObject -Class Win32_OperatingSystem
Write-Output "Operating system is $($os_info.Caption), version $($os_info.Version)"
# Getting OS build number
$os_build = [int] $os_info.BuildNumber
<#
PHASE 2: SUPPORTED LANGUAGES
#>
<#
ISO Language Code Table: http://www.lingoes.net/en/translator/langcode.htm
Supported languages are defined by TXT files containing translations of the "OK messages" you can find looking at the chkdsk event log.
Lang file needs to have the following three lines and syntax:
8= Message1;Message2;Message3
7= Message4;Message5;Message6
bad= bad sectors
After the "8= " you just write the message you can find in the logs for Windows 8/10; after the "7= " it is the same, but for Windows 7; after the "bad= " you write how to say "bad sectors" in that language.
Since this script will be uploaded as a component in Datto RMM, it will search for the TXT files inside of the current folder, exluding the command.ps1 file, that is the script itself.
#>
# Getting supported languages from TXT file list
$supported_lang =
Get-ChildItem -Path .\ |
Where-Object {$_.Name -ne "command.ps1"} |
ForEach-Object {
Write-Output $_.Name.TrimEnd(".txt")
}
# Checking if installed language is supported
Write-Output "Installed language is $((Get-Culture).DisplayName)"
# If not supported
if ($supported_lang -notcontains $PSCulture) {
# Stopping the script
Write-Output "Installed language is not supported."
exit 1
}
# Getting the lang file content
$lang_file = Get-Content -Path .\$PSCulture.txt
# Defining how to say "bad sectors" in the installed language
$bad_sectors = $lang_file[2].TrimStart("bad= ")
# Defining OK messages based on OS build
# If OS is Windows 8 or greater
if ($os_build -ge 9200) {
$ok_messages = $lang_file[0].TrimStart("8= ").Split(";")
# Also defining /scan parameter for chkdsk command
$scan = "/scan"
# If OS is Windows 7
} elseif ($os_build -lt 9200 -and $os_build -ge 7600) {
$ok_messages = $lang_file[1].TrimStart("7= ").Split(";")
# If OS is not not supported
} else {
# Stopping the script
Write-Output "Installed operating system is not supported."
exit 1
}
<#
PHASE 3: VOLUMES
#>
# Getting volumes where drive type is fixed and capacity is at least 200 MB
Get-WmiObject -Class Win32_Volume |
Where-Object {$_.DriveType -eq 3} |
Where-Object {$_.Capacity -ge 200000000} |
# For each volume found
ForEach-Object {
# Writing a message before starting showing the volume name and label
Write-Output "=============================================
Running Check Disk on volume $($_.Name)
Label: $($_.Label)
"
# Getting volume ID (used to run chkdsk command)
$volume_id = $_.DeviceID.TrimEnd("\")
# Creating a short volume ID removing forbidden characters (used to name the log file)
$volume_short_id = $volume_id.TrimStart("\\?\Volume{").TrimEnd("}")
<#
PHASE 4: LOGS
#>
# Creating a variable containing the logs folder's complete path
$logs_folder = "C:\chkdsk_logs"
# Creating a variable containing the log file's complete path (used to save it)
$log_path = "$logs_folder\chkdsk_log_$volume_short_id.log"
# Creating the logs folder
New-Item -ItemType Directory -Path C:\ -Name chkdsk_logs -ErrorAction SilentlyContinue |
Out-Null
<#
PHASE 5: CHECK DISK
#>
# Running chkdsk and saving log file
chkdsk $scan $volume_id |
Out-File -FilePath $log_path
# Checking if some of the OK messages are not found in the log file
$ok_messages |
# For each of the messages
ForEach-Object {
# Getting the content of the log file only if it contains one of the messages
$log_content = Get-Content -Path $log_path
$log_ok =
$log_content |
Select-String -Pattern $_
# If the found content is empty
if ($log_ok -eq $null) {
# Showing the OK message that is missing
Write-Output "Ok message missing, creating file c:\temp\chkdsk_errors_found.txt"
Write-Warning "The following message was not found in the log:
$_"
New-Item c:\temp\chkdsk_errors_found.txt
# If the found content is NOT empty
} else {
# Showing the OK message that is found
Write-Output "Showing each OK message that was found..."
Write-Output "$_
"
}
}
<#
PHASE 6: BAD SECTORS
#>
<#
This phase will compare current bad sectors with the ones from the last chkdsk.
If something has changed it will give a warning.
#>
# Creating a BadSectorsMonitor key in registry
New-Item -ItemType Directory -Path HKLM:\SOFTWARE\ -Name BadSectorsMonitor -ErrorAction SilentlyContinue |
Out-Null
# Getting bad sectors from log file
$current_bad_sectors =
$log_content |
Select-String -Pattern $bad_sectors
# Creating a string value in registry containing current bad sectors
New-ItemProperty -Path HKLM:\SOFTWARE\BadSectorsMonitor -Name CurrentBadSectors_$volume_short_id -Value $current_bad_sectors -Force |
Out-Null
# Defining previous bad sectors name and value
$previous_value_name = "PreviousBadSectors_$volume_short_id"
$previous_bad_sectors = (Get-ItemProperty -Path HKLM:\SOFTWARE\BadSectorsMonitor -Name $previous_value_name -ErrorAction SilentlyContinue).$previous_value_name
# If there is no value for previous bad sectors
if ($previous_bad_sectors -eq $null) {
# Creating value for previous bad sectors
New-ItemProperty -Path HKLM:\SOFTWARE\BadSectorsMonitor -Name $previous_value_name -Value $current_bad_sectors -Force |
Out-Null
# If there is a value for previous bad sectors
} else {
# Comparing the PreviousBadSectors value and the CurrentBadSectors value
# If they are equal
if ($previous_bad_sectors -eq $current_bad_sectors) {
Write-Output "Bad sectors have not changed since last chkdsk."
# If they are not equal
} else {
Write-Warning "Bad sectors have changed since last chkdsk."
Write-Warning "Previous: $previous_bad_sectors."
Write-Warning "Current: $current_bad_sectors."
}
# Overwriting the previous value with the current value
Set-ItemProperty -Path HKLM:\SOFTWARE\BadSectorsMonitor -Name $previous_value_name -Value $current_bad_sectors -Force |
Out-Null
}
}
# Writing a message when completed
Write-Output "=============================================
chkdsk completed on all volumes! Logs can be found in $logs_folder."
#final exit step, if any volume had errors then line 202 creates a file that we can check for and exit 1 if found.
Write-Output "Checking for presense of chkdsk errors file..."
$FileName = "c:\temp\chkdsk_errors_found.txt"
if (Test-Path $FileName) {
Write-Output "File Exists"
Write-Output "Chkdsk errors file was found, this means chkdsk errors were found, read the logs, exiting script with exit 1"
$ReturnFail
}
else
{
Write-Output "No chkdsk errors file found so not chkdsk errors were found, exiting script with exit 0."
$ReturnSuccess
}
### End of script code
}
### end of initiator script
exit $ReturnCode
Couple of things to note:
#1 - under the 4. Write start script, the script must start with Param as shown, nothing can be in front or above it, otherwise Param won't be recognized
#2 - also under the 4. Write start script, the -ScriptBlock must be immediately followed by the { character, so not as they show where it's in a line below and has spaces in front.
I want to share this with everyone as it became useful to us, but here is the final chkdsk script and leading start, the chkdsk script checks all volumes on the booted up SureBackup Veeam Lab isolated Windows machine for ntfs integrity errors and if any are found a file is created and then the script exits 1 if that file is found, which is the error code that SureBackup will detect and use as indication of a failure so the job will show failed.
This gets added to the application group test scripts, using as the article above shows and adding the %vm_ip% to the Arguments. I also tested with a domain admin account and that failed as the VM doesn't have access to the domain and it doesn't appear to accept cached creds on the VM, so I used a local admin account on the VM.
I did not create the script after PHASE 1, other than adding in the changes I needed so it would exit and create a file if an error was found during chkdsk. I further plan to re-adapt this using Repair-Volume rather than chkdsk.
Create any name ps1 script with the data immediately below:
Param($TestVmIP)
$ReturnCode = 1
$CredObject = Import-Clixml -Path C:\VeeamScript\CredObject.xml
$ReturnCode = Invoke-Command -Credential $CredObject -Computername $TestVmIP -ErrorAction Stop -ScriptBlock{
### Start of script code
$ReturnFail = 1
$ReturnSuccess = 0
<#
PHASE 1: OPERATING SYSTEM INFO
#>
# Getting OS info and displaying it
Write-Output "Computer hostname is $env:computername"
$folderPath = "c:\temp"
if (!(Test-Path $folderPath -PathType Container)) {
New-Item -ItemType Directory -Force -Path $folderPath
}
New-Item en-CA.txt
New-Item en-US.txt
Add-Content en-US.txt ("8= Windows has scanned the file system and found no problems;No further action is required; 0 KB in bad sectors")
Add-Content en-US.txt ("7= Windows has checked the file system and found no problems; 0 KB in bad sectors")
Add-Content en-US.txt ("bad= bad sectors")
Add-Content en-CA.txt ("8= Windows has scanned the file system and found no problems;No further action is required; 0 KB in bad sectors")
Add-Content en-CA.txt ("7= Windows has checked the file system and found no problems; 0 KB in bad sectors")
Add-Content en-CA.txt ("bad= bad sectors")
$os_info = Get-WmiObject -Class Win32_OperatingSystem
Write-Output "Operating system is $($os_info.Caption), version $($os_info.Version)"
# Getting OS build number
$os_build = [int] $os_info.BuildNumber
<#
PHASE 2: SUPPORTED LANGUAGES
#>
<#
ISO Language Code Table: http://www.lingoes.net/en/translator/langcode.htm
Supported languages are defined by TXT files containing translations of the "OK messages" you can find looking at the chkdsk event log.
Lang file needs to have the following three lines and syntax:
8= Message1;Message2;Message3
7= Message4;Message5;Message6
bad= bad sectors
After the "8= " you just write the message you can find in the logs for Windows 8/10; after the "7= " it is the same, but for Windows 7; after the "bad= " you write how to say "bad sectors" in that language.
Since this script will be uploaded as a component in Datto RMM, it will search for the TXT files inside of the current folder, exluding the command.ps1 file, that is the script itself.
#>
# Getting supported languages from TXT file list
$supported_lang =
Get-ChildItem -Path .\ |
Where-Object {$_.Name -ne "command.ps1"} |
ForEach-Object {
Write-Output $_.Name.TrimEnd(".txt")
}
# Checking if installed language is supported
Write-Output "Installed language is $((Get-Culture).DisplayName)"
# If not supported
if ($supported_lang -notcontains $PSCulture) {
# Stopping the script
Write-Output "Installed language is not supported."
exit 1
}
# Getting the lang file content
$lang_file = Get-Content -Path .\$PSCulture.txt
# Defining how to say "bad sectors" in the installed language
$bad_sectors = $lang_file[2].TrimStart("bad= ")
# Defining OK messages based on OS build
# If OS is Windows 8 or greater
if ($os_build -ge 9200) {
$ok_messages = $lang_file[0].TrimStart("8= ").Split(";")
# Also defining /scan parameter for chkdsk command
$scan = "/scan"
# If OS is Windows 7
} elseif ($os_build -lt 9200 -and $os_build -ge 7600) {
$ok_messages = $lang_file[1].TrimStart("7= ").Split(";")
# If OS is not not supported
} else {
# Stopping the script
Write-Output "Installed operating system is not supported."
exit 1
}
<#
PHASE 3: VOLUMES
#>
# Getting volumes where drive type is fixed and capacity is at least 200 MB
Get-WmiObject -Class Win32_Volume |
Where-Object {$_.DriveType -eq 3} |
Where-Object {$_.Capacity -ge 200000000} |
# For each volume found
ForEach-Object {
# Writing a message before starting showing the volume name and label
Write-Output "=============================================
Running Check Disk on volume $($_.Name)
Label: $($_.Label)
"
# Getting volume ID (used to run chkdsk command)
$volume_id = $_.DeviceID.TrimEnd("\")
# Creating a short volume ID removing forbidden characters (used to name the log file)
$volume_short_id = $volume_id.TrimStart("\\?\Volume{").TrimEnd("}")
<#
PHASE 4: LOGS
#>
# Creating a variable containing the logs folder's complete path
$logs_folder = "C:\chkdsk_logs"
# Creating a variable containing the log file's complete path (used to save it)
$log_path = "$logs_folder\chkdsk_log_$volume_short_id.log"
# Creating the logs folder
New-Item -ItemType Directory -Path C:\ -Name chkdsk_logs -ErrorAction SilentlyContinue |
Out-Null
<#
PHASE 5: CHECK DISK
#>
# Running chkdsk and saving log file
chkdsk $scan $volume_id |
Out-File -FilePath $log_path
# Checking if some of the OK messages are not found in the log file
$ok_messages |
# For each of the messages
ForEach-Object {
# Getting the content of the log file only if it contains one of the messages
$log_content = Get-Content -Path $log_path
$log_ok =
$log_content |
Select-String -Pattern $_
# If the found content is empty
if ($log_ok -eq $null) {
# Showing the OK message that is missing
Write-Output "Ok message missing, creating file c:\temp\chkdsk_errors_found.txt"
Write-Warning "The following message was not found in the log:
$_"
New-Item c:\temp\chkdsk_errors_found.txt
# If the found content is NOT empty
} else {
# Showing the OK message that is found
Write-Output "Showing each OK message that was found..."
Write-Output "$_
"
}
}
<#
PHASE 6: BAD SECTORS
#>
<#
This phase will compare current bad sectors with the ones from the last chkdsk.
If something has changed it will give a warning.
#>
# Creating a BadSectorsMonitor key in registry
New-Item -ItemType Directory -Path HKLM:\SOFTWARE\ -Name BadSectorsMonitor -ErrorAction SilentlyContinue |
Out-Null
# Getting bad sectors from log file
$current_bad_sectors =
$log_content |
Select-String -Pattern $bad_sectors
# Creating a string value in registry containing current bad sectors
New-ItemProperty -Path HKLM:\SOFTWARE\BadSectorsMonitor -Name CurrentBadSectors_$volume_short_id -Value $current_bad_sectors -Force |
Out-Null
# Defining previous bad sectors name and value
$previous_value_name = "PreviousBadSectors_$volume_short_id"
$previous_bad_sectors = (Get-ItemProperty -Path HKLM:\SOFTWARE\BadSectorsMonitor -Name $previous_value_name -ErrorAction SilentlyContinue).$previous_value_name
# If there is no value for previous bad sectors
if ($previous_bad_sectors -eq $null) {
# Creating value for previous bad sectors
New-ItemProperty -Path HKLM:\SOFTWARE\BadSectorsMonitor -Name $previous_value_name -Value $current_bad_sectors -Force |
Out-Null
# If there is a value for previous bad sectors
} else {
# Comparing the PreviousBadSectors value and the CurrentBadSectors value
# If they are equal
if ($previous_bad_sectors -eq $current_bad_sectors) {
Write-Output "Bad sectors have not changed since last chkdsk."
# If they are not equal
} else {
Write-Warning "Bad sectors have changed since last chkdsk."
Write-Warning "Previous: $previous_bad_sectors."
Write-Warning "Current: $current_bad_sectors."
}
# Overwriting the previous value with the current value
Set-ItemProperty -Path HKLM:\SOFTWARE\BadSectorsMonitor -Name $previous_value_name -Value $current_bad_sectors -Force |
Out-Null
}
}
# Writing a message when completed
Write-Output "=============================================
chkdsk completed on all volumes! Logs can be found in $logs_folder."
#final exit step, if any volume had errors then line 202 creates a file that we can check for and exit 1 if found.
Write-Output "Checking for presense of chkdsk errors file..."
$FileName = "c:\temp\chkdsk_errors_found.txt"
if (Test-Path $FileName) {
Write-Output "File Exists"
Write-Output "Chkdsk errors file was found, this means chkdsk errors were found, read the logs, exiting script with exit 1"
$ReturnFail
}
else
{
Write-Output "No chkdsk errors file found so not chkdsk errors were found, exiting script with exit 0."
$ReturnSuccess
}
### End of script code
}
### end of initiator script
exit $ReturnCode
-
- Service Provider
- Posts: 26
- Liked: 3 times
- Joined: Apr 19, 2017 3:47 pm
- Full Name: Ryan Faulkner
- Contact:
Re: SureBackup and a Powershell script
My script above though working, isn't working properly with Veeam, no matter the exit code within the code script itself, the part that is run on the powered on SureBackup VM, the job always ends in code 0 as success, so that part still isn't working here. So I don't know if it's my syntax or Veeam itself yet, I'm leaning towards my syntax.
-
- Service Provider
- Posts: 2
- Liked: never
- Joined: Jul 10, 2019 2:44 pm
- Full Name: Darrin Harman
- Contact:
Re: SureBackup and a Powershell script
You aren't providing an exit code. You have your exit code inside the quotes for your write-host, so you're just telling PowerShell to write some text and it won't interpret it as the exit code.
In the lines where you have $ReturnFail and $ReturnSuccess, you need to call Exit. You might be able to do this
Exit $ReturnSuccess
or
Exit $ReturnFail
since you are setting those values earlier in the script. You could also just not worry about setting those values and just do
#Exit with Success
Exit 0
and
#Exit with fail
Exit 1
In the lines where you have $ReturnFail and $ReturnSuccess, you need to call Exit. You might be able to do this
Exit $ReturnSuccess
or
Exit $ReturnFail
since you are setting those values earlier in the script. You could also just not worry about setting those values and just do
#Exit with Success
Exit 0
and
#Exit with fail
Exit 1
-
- Service Provider
- Posts: 26
- Liked: 3 times
- Joined: Apr 19, 2017 3:47 pm
- Full Name: Ryan Faulkner
- Contact:
Re: SureBackup and a Powershell script
Hey dharmandds,
I figured out the problem is that if my script exits with "exit 0" powershell is adding extra breaks. I have been able to get it to exit 1 without extra breaks, so here is the new end of my script, I know it's not perfect but right now if the scriptblock does end in 1 then it'll exit 1 without extra breaks, which Veeam does see as exit code 1.
chkdsk completed on all volumes! Logs can be found in $logs_folder."
if(Test-path $chkdskerrorlogfile -PathType leaf)
# if true do something
$Return = 1
}
else
{
# if false do something
$Return = 0
}
$Return
}
if ($ReturnCode -eq 1) {$ReturnCode = 1}
if ($ReturnCode -eq 0) {$ReturnCode = 0}
Return $ReturnCode
So above, if I change the $Return = 0 to 1, under the # if false do something, then the script will end with exit 1 and without extra breaks, if I run the script as is with $Return = 0, the scriptblock or the script itself is added 2 or 3 extra breaks at the end.

https://ibb.co/XYkDFrN
I figured out the problem is that if my script exits with "exit 0" powershell is adding extra breaks. I have been able to get it to exit 1 without extra breaks, so here is the new end of my script, I know it's not perfect but right now if the scriptblock does end in 1 then it'll exit 1 without extra breaks, which Veeam does see as exit code 1.
chkdsk completed on all volumes! Logs can be found in $logs_folder."
if(Test-path $chkdskerrorlogfile -PathType leaf)
# if true do something
$Return = 1
}
else
{
# if false do something
$Return = 0
}
$Return
}
if ($ReturnCode -eq 1) {$ReturnCode = 1}
if ($ReturnCode -eq 0) {$ReturnCode = 0}
Return $ReturnCode
So above, if I change the $Return = 0 to 1, under the # if false do something, then the script will end with exit 1 and without extra breaks, if I run the script as is with $Return = 0, the scriptblock or the script itself is added 2 or 3 extra breaks at the end.
https://ibb.co/XYkDFrN
Who is online
Users browsing this forum: Google [Bot], joast, Semrush [Bot] and 124 guests