Search code examples
powershelllogonserver

Return Statement not Working with continue


Update

I was able to resolve this by changing Rename-Item to Move-Item and just changing the name in the process. However, this does not solve the mystery of why the return statement was not executed, or at least if it was, why the function continued to call New-Item.


I am trying to rename an item at logon, but if the item doesn't exist, I want to create it. Here is the function which does this:

function SelfHelpAppData {
    $ErrorActionPreference = "Stop"
    trap {Log-Error $_ $MyInvocation.MyCommand; Continue}

    $files = Get-ChildItem $AppData

    ForEach ($file in $files) {
        If ($file.Name -match 'qxjz') {

            Rename-Item $file.PSPath "qxjz$env:COMPUTERNAME.txt" -Force
            WriteLogonEntryData
            return
        }
    }

    New-Item "$AppData\qxjz$env:COMPUTERNAME.txt"
    WriteLogonEntryData
}

However, when this runs, I am receiving these errors in my log:

Windows PowerShell is in NonInteractive mode. Read and Prompt functionality is not available.

At \DC1\NETLOGON\PSSubs\mainlogon.ps1:841 char:5

  • New-Item "$AppData\qxjz$env:COMPUTERNAME.txt"
    
  • ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    

And then:

Cannot create a file when that file already exists.

At \DC1\NETLOGON\PSSubs\mainlogon.ps1:835 char:13

  •         Rename-Item $file.PSPath "qxjz$env:COMPUTERNAME.txt" -Force
    
  •         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    

But this is impossible, as if the first line (rename-item) attempted to run, then the function should have returned before the other line had a chance. I have tried changing the return statement to return $null but with no effect. Does anyone know what is going on here?


Here is the Log-Error code:

function Log-Error {
    param (
        $error,
        [string]$sub
    )
    $ErrorActionPreference = "Stop"
    trap {Log-Error $_ $MyInvocation.MyCommand; Continue}

    $filename = "\\file\administration\Unused\LogonScriptErrors\$env:USERNAME - $env:COMPUTERNAME - $(Get-Date -Format ddMMyyyy-HHmmss) - $($error.InvocationInfo.ScriptLineNumber).log"

    New-Item $filename -ItemType File -Value "$($error.Exception.Message) `r`n `r`n $($error.InvocationInfo.PositionMessage) `r`n `r`n $sub"
}

Solution

  • The reason for the behavior you observed is the continue in your trap statement list. It causes the script to continue with the next instruction after the loop where the error occurred. This is documented behavior.

    If you want the script to terminate operation in case of an error remove the continue. If you want it just exit from the function change continue to return.

    With that said, I'd recommend to move away from trap and use try/catch instead, which offers better control, even visually.

    BTW, the New-Item error occurs, because you omitted the mandatory parameter -Type. Without that parameter the cmdlet tries to prompt you for the required information, but can't because the script is run non-interactively. To get rid of the error add -Type File to the statement.