Question:
In a post-deployment script used in a continuous integration pipeline (Azure DevOps), I’m removing old files.
Basically, it’s a PowerShell script that removes every release folder but the current one in the deployment directory.
Sometimes, the Remove-Item fails for some reason (old file still opened by someone one the deplyoment machine, for instance)
It’s not a big deal. I don’t want an error saying my whole deployment failed because of this. However, I want a warning, so I’m aware that it happened.
For instance (MCVE):
1 2 |
Remove-Item INEXISTENT_FILE |
Problem : it causes an error.
Attempt 1 :
1 2 |
Remove-Item INEXISTENT_FILE -ErrorAction SilentlyContinue |
Problem : It removes the Error completely, that’s not what I want (I want a warning)
Attempt 2 : I tried to use ErrorVariable as recommended here : https://devblogs.microsoft.com/powershell/erroraction-and-errorvariable/
1 2 3 4 5 |
Remove-Item INEXISTENT_FILE -ErrorAction SilentlyContinue -ErrorVariable $removeItemError if ($removeItemError) { Write-Warning "Warning, something failed!" } |
Problem : it doesn’t work, it doesn’t show the if
part. If I remove “SilentlyContinue” error action, it just emits an error, and in any case never goes into the if
part.
Attempt 3 : I tried to use also Try Catch block as proposed here : PowerShell -ErrorAction SilentlyContinue Does not work with Get-ADUser
1 2 3 4 5 6 7 |
Try { Remove-Item INEXISTENT_FILE } Catch { Write-Warning "Warning, something failed!" } |
Problem : it never goes into the catch block either (!?)
Anyone has another option to show a warning instead of an error if Remove-Item fails ?
Answer:
The error produced by Remove-Item
is considered ‘non-terminating’, which means that it is ignored by ‘try/catch’. To force it to become ‘visible’ to ‘try/catch’ use the ErrorAction
parameter:
Remove-Item INEXISTENT_FILE -ErrorAction Stop
Alternatively, you can change this at the script level (i.e. for all subsequent commands) like this:
$ErrorActionPreference = 'Stop'
The error message can be retrieved using $_.Exception.Message
or $error[0]