简体   繁体   中英

Powershell warning and error handling

The following code I am writing to replace a batch script which I have below.

$Script:srcpath = ((Get-Location).Path)
$Script:configure = "$Script:srcpath\qtbase\configure.bat"

if (Get-Item "$Script:srcpath\qtbase\configure.bat" -WarningAction (Write-Warning "$Script:configure not found. Did you forget to run 'init-repository'?")) {
    continue
}

I am try to rewrite the qt configure batch script:

set "srcpath=%~dp0"
set "configure=%srcpath%qtbase\configure.bat"
if not exist "%configure%" (
    echo %configure% not found. Did you forget to run "init-repository"? >&2
    exit /b 1
)

if not exist qtbase mkdir qtbase || exit /b 1

echo + cd qtbase
cd qtbase || exit /b 1

echo + %configure% -top-level %*
call %configure% -top-level %*
set err=%errorlevel%

cd ..

exit /b %err%

The error I am getting in PowerShell is the following:

Get-Item : Cannot bind parameter 'WarningAction' to the target. Exception setting
"WarningAction": "Object reference not set to an instance of an object."
At line:4 char:67
+ ... rningAction (Write-Warning "$Script:configure not found. Did you forg ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (:) [Get-Item], ParameterBindingException
    + FullyQualifiedErrorId : ParameterBindingFailed,Microsoft.PowerShell.Commands.GetItemCommand

The problem is the error being thrown is erroneous because the warning am calling is what should take its place to tell people that the item doesn't exist. so run "init-repository".

There isn't a good, "if not exist" in PowerShell.

Okay, there is, but it looks like this:

catch [System.Management.Automation.ItemNotFoundException]

which I am having problems with getting to work.

Why am I doing this before someone asks is because I feel that Microsoft will phase out CMD some time it's good to have updated scripts.

Why it's not working

WarningAction does not work like that.

From the about_CommonParameters documentation :

Determines how the cmdlet responds to a warning from the command. "Continue" is the default value. This parameter works only when the command generates a warning message. For example, this parameter works when a command contains the Write-Warning cmdlet.

So essentially the value of WarningAction is Continue by default and can be set to Inquire , SilentlyContinue or Stop . The value it is set to determines what action is taken if the Get-item command throws a warning, not what warning to write if Get-item throws a warning.

You can change the preference variable $WarningPreference to set the WarningAction within the current scope, or precede by a scope modifier.


How to get it to work

Test-Path

I second Richard's comment to use Test-Path . This will return True or False , depending on whether it finds the file.

if (-not (Test-Path -Path "$Script:srcpath\qtbase\configure.bat")){
    Write-Warning 'Does not exist!'
    # do other stuff
    continue
}else{
    Get-Item $configure
}

try / catch

You could try to catch the exception thrown by Get-Item directly in a try/catch . In a similar way to WarningAction , there is ErrorAction which determines what to do if an error is thrown. Terminating error is required, so ErrorAction is set to Stop .

try{
    Get-Item $configure -ErrorAction Stop
}catch [System.Management.Automation.ItemNotFoundException]{
    Write-Output "Item not found"
    # do other stuff
}catch{
    Write-Output "Some other error"
    $Error[0] # prints last error
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM