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"
}
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.