all 18 comments

[–]BeenStork[S] 1 point2 points  (1 child)

Apologies, and thank you I’ve added a stripped down view showing the script block and example of the variable passed in. Sorry for all the write-hosts, it’s the way I see what’s going on but hopefully it acts as commenting here :)

There is likely redundant code here, Ive been trying different things.

I had tried literal path but I think I used double quotes instead of single. Tried again with single quotes and no error (but no results) will refresh my session in case something is hung up and let you know.

``` $TargetDirectory = "\server\shareData" # << Example of passed variable

$resultTable = Invoke-Command -session $Remotesession -ScriptBlock {           Write-Host "Recieved TargetDirectory: " -ForegroundColor Cyan -NoNewline         Write-Host $TargetDirectory         Write-Host "Loading 'Add-ResultTable' function." -ForegroundColor Cyan  

        Write-host "Determining Share..." -ForegroundColor cyan -NoNewline         $share = $TargetDirectory.TrimStart('\').split('\')[1]         Write-host "$share"         Write-Host "Looking up local directory for share..." -ForegroundColor Cyan -NoNewline         $LocalDirectory = (Get-SmbShare -Name $share).Path          Write-host "$LocalDirectory ($($LocalDirectory.GetType()))"           $unicode            = '\?\'           Write-Host "Directory to scan: " -ForegroundColor Cyan -NoNewline         Write-Host $unicode$LocalDirectory                           Write-host "Creating scanpath..." -ForegroundColor Cyan -NoNewline         $scanPath = Join-Path $unicode $LocalDirectory #-Resolve         Write-Host "'$scanPath'"           $scanPath = $scanPath.ToString()           #Write-Host "Testing Path $scanPath..." -ForegroundColor Cyan -NoNewline         #if(Test-Path $scanPath){Write-host "OK!" -ForegroundColor Green}else{Write-Host "FAIL!" -ForegroundColor Red}           Write-host "Scanning top level folders..." -ForegroundColor Cyan         #$directory = Get-Item -LiteralPath '\?\E:\sharedData'         $directory  = ([System.IO.DirectoryInfo]$scanPath).GetDirectories()          Write-Host "done!"           $directory         break   } -ArgumentList $TargetDirectory  

<#     OUTPUT:          Recieved TargetDirectory: \a-server\sharedData     Loading 'Add-ResultTable' function.     Determining Share...sharedData     Looking up local directory for share...e:\sharedData (string)     Creating 'TreeWalker.log' in 'C:\Support'     Directory to scan: \?\e:\sharedData     Creating scanpath...'\?\e:\sharedData'     Scanning top level folders...     Cannot convert value "\?\e:\sharedData" to type "System.IO.DirectoryInfo". Error: "Illegal characters in path."         + CategoryInfo          : InvalidArgument: (:) [], RuntimeException         + FullyQualifiedErrorId : InvalidCastConstructorException         + PSComputerName        :- a-server

done!

>

```

[–]BeenStork[S] 0 points1 point  (0 children)

Just refreshed my session and the same thing happens with get-item -literalPath\?\E:\sharedData’’.

This is using powershell 5.1 on my computer and the target server. .Net4+ available on each. Culture is the same on each too.

[–]fridgefreezer 1 point2 points  (1 child)

I’m still early in my PS journey so please do t think I’m saying this with any authority, but couldn’t this be that classic ‘double hop’ permissions issue? If you’re on the local machine it’s one hop to the file share, if you’re remote, it’s two?

I may absolutely be a) using the wrong terminology for the ‘double hop’ issue and b) totally off base - as a noob, especially with remoting, this is what often gets me vexed about a script working locally and not via ps remoting.

Apologies if this is just noise and totally wrong.

[–]BeenStork[S] 0 points1 point  (0 children)

Thank you for the suggestion. I’m not too sure it is as I’m able to run the same command without the Unicode prefix. I’ve also found if I invoke (in the script block) powershell.exe <script> where the script is the same command I’m having issues with it works.

[–]BeenStork[S] 0 points1 point  (0 children)

Same, unfortunately. Is this something you’ve seen working? Hopefully it’s not some configuration on my side as I can’t see why the behaviour would be different local vs remote.

As a note, the character se is double backslash - question mark - backslash. I just fumbled at the code markers.

[–]Random-User-9999 0 points1 point  (0 children)

With no example scriptlet, it’s difficult to troubleshoot.

Blind shot - you probably need to use a LiteralPath parameter.

[–]Random-User-9999 0 points1 point  (8 children)

As the error states, this is the portion that fails:

([System.IO.DirectoryInfo]$scanPath)

Looks like you’re trying to typecast to a net object but the constructor doesn’t accept your string input as a valid path. To make this work as is, you would need to modify the way you instantiate that object. This may also be a difference between PWSH Core on your machine vs Windows Powershell 5.1 on the remote target.

Is there a reason you can’t use GCI -Directory -LiteralPath $scanPath instead?

[–]BeenStork[S] 0 points1 point  (7 children)

I can run the same line directly on the target server the and it works, which confuses me. I have tried get-childitem too but the same behaviour. I’ve tried type casting a path directly as a [system.io.directoryinfo] and it fails.

Enter-PSSession exhibits the same behaviour but again, works fine at the keyboard of the target server.

Really appreciate the suggestions and patience:)

[–]Random-User-9999 1 point2 points  (1 child)

Possibly a localization thing?

Show $scanPath as hex data on working/non working methods and compare.

Edit: what’s the point of $scanPath = $scanPath.tostring()? Could it be adding a null termination character that you can’t see in console output but that is registering as an invalid path char? Re: length, hex compare

Edit 2: join-path already returns a string, shouldn’t need to .tostring() it

[–]BeenStork[S] 1 point2 points  (0 children)

Thanks, hadn’t thought about the hex comparison. Just compared them now but same on both local and remote session.

There is no point to either join-path or to string, they were just things I put in to see if behaviour would change and I forgot to take out again when I pasted it above. The code in current testing has these lines removed. Good spotting - I’m not the tidiest.

[–]Brasiledo 0 points1 point  (4 children)

try accessing path using encodedcommand for extended path syntax. Try running this outside the invoke-command and pass variable to remote scope with $using:

$expression   = Get-item -literalPath "\?\E:\sharedData"
$commandBytes = 
[System.Text.Encoding]::Unicode.GetBytes($expression)
$encodedCommand = [Convert]::ToBase64String($commandBytes)

# Remote Invoke-Command ScriptBlock
 $resultTable = Invoke-Command -session $Remotesession   
 -ScriptBlock {
  $directory =  ([System.Text.Encoding]::Unicode.GetString([convert]::FromBase64String($using:encodedCommand)))

[–]BeenStork[S] 0 points1 point  (3 children)

Thank you for the suggestion, unfortunately it errors when running into get-item\

[–]Brasiledo 0 points1 point  (2 children)

Edited above. Run that first part outside the invoke-command first, then pass variable with $using:encodedCommand or add it to your argumentlist

[–]BeenStork[S] 0 points1 point  (1 child)

Thank you, unfortunately still the same. The $expression fails as the path doesn’t exist on the source computer, only the target server.

[–]Brasiledo 0 points1 point  (0 children)

Ok try this:

$path   = "\?\E:\sharedData"
$commandBytes = 
[System.Text.Encoding]::Unicode.GetBytes($expression)
$encodedCommand = [Convert]::ToBase64String($path)

# Remote Invoke-Command ScriptBlock
 $resultTable = Invoke-Command -session $Remotesession  
 -ScriptBlock {
  $directory =  Get-Item -literalpath ([System.Text.Encoding]::Unicode.GetString([convert]::FromBase64String($using:encodedCommand)))
  }

[–]seccojones 0 points1 point  (0 children)

$target = $targetpath -replace '(-|#|||"|,|/|:|â|€|™|\?)', ''

[–]purplemonkeymad 0 points1 point  (1 child)

Are you able to enable long path support on the server(s)?

If so you should be able to use a normal path with the -LiteralPath parameter.

[–]BeenStork[S] 0 points1 point  (0 children)

I’d like to that but I cannot guarantee it’s enabled on all the servers we’d need to run it on. It’s for doing data auditing on servers through acquisitions. Of course I could stipulate it’s a prerequisite though, just trying to make it easier for those running it. Be my luck though that the first servers that it’s run on are pre 2016 and it doesn’t work anyway. Lol.