PowerShell Script Execution Troubleshooting Advice
Per Veeam Support Policy: Custom script troubleshooting is not supported.
What's in Scope:
- Confirming that the Veeam task executed the script.
- Assisting with Veeam PowerShell cmdlets not functioning as intended or documented.
What's Out of Scope:
- Troubleshooting why a custom script did not function as intended.
Purpose
This article is intended to serve as a helpful resource from the Veeam Support team, offering straightforward guidance for those navigating the complexities of troubleshooting script failures. Please note, the advice provided within this article is given in good faith and without warranty.
This article provides advice on methods to troubleshoot PowerShell scripts that are executed as part of:
- Pre-Freeze and Post-Thaw Scripts for vSphere or Hyper-V VMs.
- Scripts that are configured to run before or after jobs run (e.g., Backup Jobs, Backup Copy Jobs, Replication Jobs, etc.)
Solution
PowerShell Script Execution Details
Pre-Freeze and Post-Thaw scripts are:
- uploaded to the Guest OS of the VM and executed with the command:
powershell.exe -ExecutionPolicy ByPass -Command try { . 'C:\Windows\{guid}\<script>.ps1' -ErrorAction Stop } catch { exit 1 }
- executed using the account assigned within the Guest Processing settings.
Pre-Job and Post-Job scripts are:
- executed on the Veeam Backup Server using the command:
powershell.exe -ExecutionPolicy ByPass -Command try {& '<path-to-script>' -ErrorAction Stop } catch { exit 1 }
- executed using the account assigned to the 'Veeam Backup Service'. By default, that account is 'Local System'.
General Advice
This section will provide advice on changes you can make to your script to help with troubleshooting.
For this example, here is a simple script that identifies the most recently modified file in a folder and then copies it to a folder.
$LatestLog = get-childitem -Path 'C:\MonitoringLogs\' | sort-object LastWriteTime | select-object -last 1 Copy-Item $LatestLog.FullName D:\Backup\
- Add logging to the PowerShell script itself so that you can check what errors the script may have thrown when being executed. This can be done by adding 'Start-Transcript -path C:\temp\scriptlog.txt' to the first line of the script and adding 'Stop-Transcript' to the last line.
Start-Transcript -path C:\temp\scriptlog.txt $LatestLog = get-childitem -Path 'C:\MonitoringLogs\' | sort-object LastWriteTime | select-object -last 1 Copy-Item $LatestLog.FullName D:\Backup\ Stop-Transcript
- After adding the Start-Transcript cmdlet to the script, make the actions within your script more verbose. For example:
- If the script contains a variable, have the script announce the variable using Write-Host so that it appears in the transcript log. For example:
Start-Transcript -path C:\temp\scriptlog.txt $LatestLog = get-childitem -Path 'C:\MonitoringLogs\' | sort-object LastWriteTime | select-object -last 1 Write-Host $LatestLog Copy-Item $LatestLog.FullName D:\Backup\ Stop-Transcript
- If the script uses a command that can have a -verbose flag added, add it so that the transcript log will contain more information. For example:
Start-Transcript -path C:\temp\scriptlog.txt $LatestLog = get-childitem -Path 'C:\MonitoringLogs\' | sort-object LastWriteTime | select-object -last 1 Write-Host $LatestLog Copy-Item $LatestLog.FullName D:\Backup\ -verbose Stop-Transcript
- If the script contains a variable, have the script announce the variable using Write-Host so that it appears in the transcript log. For example:
Conclusion
Now, this simple script, when run, will also write out a log file containg:
- Full PowerShell headers documenting what command was used to call it, as well as what user ran it.
- What file it determined to be the $LatestLog
- What the outcome of the Copy-Item command was.
Troubleshooting Pre-Freeze/Post-Thaw Scripts
Test running the script from within the Guest OS of the VM using the account assigned within the Guest Processing settings of the job.
- Connect to the Guest OS of the VM using the account that Veeam Backup & Replication is configured to use for Guest Processing.
- Copy the script manually to the Guest OS.
- Open an elevated PowerShell prompt.
- Update the 'C:\path\to\script.ps1' path in this example command and execute it.
This command is the same as the one Veeam Backup & Replication uses to trigger the script.
powershell.exe -ExecutionPolicy ByPass -Command "& {try {& 'C:\scripts\testscript.ps1' -ErrorAction Stop } catch { exit 1 }}"
- Observe the outcome. If it fails, resolve the errors shown, save the script, and test it again.
Troubleshooting Pre-Job/Post-Job Scripts
Pre-Job/Post-Job scripts are executed on the Veeam Backup Server, using the account assigned to the Veeam Backup Service.
To begin direct script troubleshooting you will first need to identify which account Veeam will use to run the script, that way you can test your script using the same account.
Identify Veeam Backup Service Account
Open services and check which account is listed in the 'Log On As' column for the Veeam Backup Service.
Or, check via PowerShell using:
Get-WmiObject Win32_Service -Filter "Name='VeeamBackupSvc'" | Select-Object Name,StartName
Service Account is Local or Domain User
If the Veeam Backup Service is running under an actual user account, login as that account and test the script using the following command. This command is directly based on the method Veeam Backup & Replication uses to call the script:
powershell.exe -ExecutionPolicy ByPass -Command "& {try {& 'C:\scripts\testscript.ps1' -ErrorAction Stop } catch { exit 1 }}"
Service Account is LocalSystem
If the account assigned to the Veeam Backup Service is Local System, which is the most common configuration, testing the scripts manually will be a bit more difficult. There are two options for causing a script to be run using the account Local System.
Option 1: Test the Script As SYSTEM Using PsExec
This option will allow you to see any errors that are thrown immediately and allow you to rapidly rerun the script after modification to perform iterative testing more efficiently.
PsExec is available from Microsoft here: PsExec
To simulate the execution action Veeam Backup & Replication would perform as SYSTEM:
- Launch an Administrative Command Prompt and run the following command to open a PowerShell console as SYSTEM:
PsExec64.exe -s -i powershell.exe
- A new PowerShell prompt will appear.
- Update the "C:\path\to\script.ps1" in this example command and execute it.
This command is the same as the one Veeam Backup & Replication uses to trigger the script.
powershell.exe -ExecutionPolicy ByPass -Command "& {try {& 'C:\path\to\script.ps1' -ErrorAction Stop } catch { exit 1 }}"
- Observe the outcome. If it fails, resolve the errors shown, save the script, and test it again.
Option 2: Test the Script Using Task Scheduler to Run the Script As SYSTEM
- Open Task Scheduler.
- Create a New Task.
- Name the Task.
- On the General tab, in the Security options section, click 'Change User or Group...' and enter the username SYSTEM.
- On the Actions tab, add an action to "Start a program."
- For the Program/script, enter: powershell.exe
- For the Arguments field, update the 'C:\path\to\script.ps1' in the following example and insert it.
-ExecutionPolicy ByPass -Command "& {try {& 'C:\path\to\script.ps1' -ErrorAction Stop } catch { exit 1 }}"
- Run the Task.
To report a typo on this page, highlight the typo with your mouse and press CTRL + Enter.