stringpowershellfilepathillegal-characters

Powershell strings are not concatenating properly


So I have

$Logfilename = "E:\Deployment Logs\20201026 - 1_ProductInfo"
Write-Host $Logfilename
E:\Deployment Logs\20201026 - 1_ProductInfo


$Newname = $Logfilename + ".log"
Write-Host $Newname
.logeployment Logs\20201026 - 1_ProductInfo


Get-Content -Path "E:\Deployment Logs\20201026 - 1_ProductInfo.log"
#returns file normally

However, when I try to run the Get-Content from a variable name, I get this error. It's also odd because the error message shows one string, but the Write-Host above, .logeployment Logs\20201026 - 1_ProductInfo, shows a different one.

Get-Content -Path $Newname
Get-Content : Illegal characters in path.
At line:1 char:1
+ Get-Content -Path $Newname
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (E:\Deployment L...roductInfo.log:String) [Get-Content], ArgumentException
    + FullyQualifiedErrorId : ItemExistsArgumentError,Microsoft.PowerShell.Commands.GetContentCommand
 
Get-Content : Cannot find path 'E:\Deployment Logs\20201026 - 1_ProductInfo.log' because it does not exist.
At line:1 char:1
+ Get-Content -Path $Newname
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (E:\Deployment L...roductInfo.log:String) [Get-Content], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

I am completely lost as to what is happening here. The file definitely exists at the given path. I have tried adding a .replace for hidden \r and \n characters to no avail. I have tried writing the variable contents via Out-String and adding the .log then and the same thing happens. Is there any explanation or fix to this?


Solution

  • From the conversation in comments, your script file has a hidden Carriage Return character at the end of the string in the line $Logfilename = "E:\Deployment Logs\20201026 - 1_ProductInfo" (which hasn't been replicated into the script in your question).

    When you output the string using write-host the Carriage Return moves the cursor back to the start of the console line and then carries on writing the rest of the string.

    A simple repro is:

    PS> "E:\Deployment Logs\20201026 - 1_ProductInfo$([char]0x000D).log"
    .logeployment Logs\20201026 - 1_ProductInfo
    

    Carriage Return is not a valid character in filenames, which is why you're also seeing the error. It also looks like it's being stripped out of the error message so it's just showing the "expected" value of the two strings concatenated:

    Get-Content : Cannot find path 'E:\Deployment Logs\20201026 - 1_ProductInfo.log' because it does not exist.
    

    This probably happened because you cut & pasted the original value from some other system and you picked up the hidden character without knowing it.

    To fix it, just delete the last few characters in the line $Logfilename = "E:\Deployment Logs\20201026 - 1_ProductInfo" and then re-type them manually. You'll probably notice as you delete characters that one of the times you press del or backspace nothing will seem to happen - that's when you're deleting the non-printing character.

    Update

    In case the comments get deleted, we solved the issue with the following tests:

    PS E:\Deployment Plans> $Logfilename.length
    44
    
    PS E:\Deployment Plans> $Newname.length
    48
    

    whereas

    PS> "E:\Deployment Logs\20201026 - 1_ProductInfo".Length
    43
    
    PS> "E:\Deployment Logs\20201026 - 1_ProductInfo.log".Length
    47
    

    which told us there was probably an extra non-printing character at the end of $Logfilename.

    Next:

    PS> [System.Text.Encoding]::UTF8.GetBytes("E:\Deployment Logs\20201026 - 1_ProductInfo.log".)
    .
    .
    73
    110
    102
    111
    

    but

    PS> [System.Text.Encoding]::UTF8.GetBytes($Logfilename)
    .
    .
    73
    110
    102
    111
    13
    

    So the extra character was UTF character 13 (decimal), which is U+000D, i.e. Carriage Return - see http://www.fileformat.info/info/unicode/char/000d/index.htm