Why is my if statement always false?

I run this script:

if (Copy-Item .\test.ps1 $env:SystemRoot\System32)
{
    Write-Host "Done."
    exit 0
}
else
{
    Write-Host "Not done."
    Write-Host "You must be root."
    exit 1
}

When I run this script as a normal user I got the message in else statement, because I am not root. And this is okay.

But I run this script as root I also got the message in else statement! But file copy operation is succeded. I can't get the message in if statement. Why?

I also check the error code and its always False.


Solution 1:

An if statement does not evaluate whether the command inside its condition ran successfully. It will only check the value (in your case the return of your command) and cast it to a bool.

Copy-Item does not return anything by default, and that's why your if statement is always false, because [bool]$null is $false.

You have three options here:

Add the -PassThru parameter to get some form of return:

if (Copy-Item .\test.ps1 $env:SystemRoot\System32 -PassThru)

Use the $? variable to see if your previous command was successful:

Copy-Item .\test.ps1 $env:SystemRoot\System32
if ($?) {
    Write-Host "Done."
    exit 0
}
else {
    Write-Host "Not done."
    Write-Host "You must be root."
    exit 1
}

However, the most reliable way would be to wrap it in Try {} Catch {} and add -ErrorAction Stop

Try {
    Copy-Item .\test.ps1 $env:SystemRoot\System32 -ErrorAction Stop
    Write-Host "Done."
    exit 0
}
Catch {
    Write-Host "Not done."
    Write-Host "You must be root."
    exit 1
}