Remote running of .exe from share not working

I’m trying to run a script which calls a .exe file on a number of servers in our AD and I’m not getting it to work as I intended.

The original script looks like this:

#Requires -version 5.1
[CmdLetBinding()]
Param ()
Try {
  $computer = $env:computername
  $dt = Get-Date -Format "yyyy/MM/dd HH:mm:ss"
  $disks = Get-CimInstance –Query "SELECT * FROM win32_logicaldisk WHERE DriveType = '3'"
  foreach($disk in $disks){
    $log = \\[SERVERSHARE]\[TOOL].exe "$($disk.DeviceID)\"
    [PSCustomObject]@{
      Time = $dt
      Server= $env:computername
      Disk = $disk.DeviceID
      Result = "$log"
    } | Export-Csv -Path '\\[SERVERSHARE]\[LOG].csv' -NoClobber -Encoding UTF8 -Append -Delimiter ";" -NoTypeInformation
    Write-Host "$computer $($disk.DeviceID) was scanned"
  }
}
Catch {
  Write-Host -BackgroundColor Red "Error: $($_.Exception)"
  Break
}

And it works if I copy the script to the remote server and logs in via RDP and runs it manually.

I tried to modify the script like this:

#Requires -version 5.1
[CmdLetBinding()]
Param ()
$Server = '[SERVER]'
Try {
  Invoke-Command -ComputerName $Server -ScriptBlock {
    $computer = $env:computername
    $dt = Get-Date -Format "yyyy/MM/dd HH:mm:ss"
    $disks = Get-CimInstance –Query "SELECT * FROM win32_logicaldisk WHERE DriveType = '3'"
    foreach($disk in $disks){
      $log = Start-Process -FilePath '\\[SERVERSHARE]\[TOOL].exe' -Argumentlist "$($disk.DeviceID)\"
      [PSCustomObject]@{
        Time = $dt
        Server= $env:computername
        Disk = $disk.DeviceID
        Result = "$log"
      } | Export-Csv -Path '\\[SERVERSHARE]\[LOG].csv' -NoClobber -Encoding UTF8 -Append -Delimiter ";" -NoTypeInformation
      Write-Host "$computer $($disk.DeviceID) was scanned"
    }
  }
}

Catch {
  Write-Host -BackgroundColor Red "Error: $($_.Exception)"
  Break
}

My thinking was that it should run the entire scriptblock from the remote server but I get two access denied permission errors. I’m guessing the first one is for trying to access the .exe file, but it doesn’t say specifically but the other one is specific about not being able to open the log file:

Access is denied
    + FullyQualifiedErrorId : System.UnauthorizedAccessException
    + PSComputerName        : [SERVER]

Access to the path '\\[SERVERSHARE]\[LOG].csv' is denied.
    + CategoryInfo          : OpenError: (:) [Export-Csv], UnauthorizedAccessException
    + FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.ExportCsvCommand
    + PSComputerName        : [SERVER]

The share is (at the moment) entirely open, so it should be no problem accessing it.

Since the modification didn’t work as I had intended I tried to do this instead:

Invoke-Command -ComputerName [SERVER] -FilePath [ORGSCRIPT]

My understanding is that it should copy the script to the remote computer and run it there, but no go!

$S = New-PSSession -ComputerName [SERVER]
Invoke-Command -Session $S -FilePath [ORGSCRIPT]

Fails as well.

I also tried

Copy-Item [ORGSCRIPT] -Destination \\[SERVER]\C$
Invoke-Command -ComputerName [SERVER] -Command { C:\[ORGSCRIPT] }

There was no problem establishing a session or copying a file, but whenever I tried to actually run it I ended up with a permission denied error message something like this:

Error: System.UnauthorizedAccessException: Access is denied ---> System.ComponentModel.Win32Exception: Access is denied
   --- End of inner exception stack trace ---
   at System.Management.Automation.Utils.NativeFileExists(String path) ... 

There’s more but you get the gist.

Am I thinking about this all wrong or should I be trying something else entirely?

If I got you right you’re trying to connect to a remote computer and remote from there to another third computer, right? That’s not possible by default and is called double hop restriction

Here you may read more about:

The two simplest and straight forward solutions would are either to copy everything you need to the remote computers and even log it locally or to run the script as a scheduled task directly from the remote computers.

Hey Olaf,
There are three computers involved, but I’m not double hopping. At least not the way I’m seeing it.

On my workstation I have my original script which I want to run on a remote server. Either by running it in its entirety on the remote server or by running the commands in the scriptblock from the Invoke-Command in the modified script.

The third computer only hosts a(n open) file share containing the executable I want to run on the servers and the log-file I want to run. So I’m not remoting to that server, I’m just calling the .exe by UNC path rather than a local file path.

Well, I might have not found the right way to describe it but I think MSFT seems to consider it different from you. :wink:

I’m afraid that still counts as a double hop. :man_shrugging:t4:

1 Like

Olaf is correct. In addition to his suggestions you could also try passing a different set of credentials than the one running the remote command to make that second hop or you could look into credssp. But if you just take a step back and think about it, you could from the calling host copy the script from host 3 to host 2, then execute the now local script on host 2.

Thank you both.

I was aware of the double hop issue, but I’d only heard about it being an issue when trying to remote administer a computer through an existing session.
I didn’t think it applied to accessing files on an open share.

Which means none of my existing solutions would work… I’m loath to copy everything over to a local disk and run and save it there, as it would mean a huge cleanup work afterwards.

@krzydoug Do you mean that I put the script on the same share as the .exe and .csv file (on host 3) and copy it from there to host 2 which is the host I want to run the script on?

Is there a meaningful difference in copying the script directly from host 1 (my workstation) to host 2 (server to be scanned) and running the script versus copying from host 3 (server with share) to host 2 and running the script?

This might be what you meant… Would it work if I RDP:d into the server with the share and ran the Invoke-Command from there? That would take my workstation out of the equation, wouldn’t it?

If you RDP that is a different situation. That would be a single hop. Any call to a 3rd hop is subject to this restriction. Here’s a quick and clear demonstration. Run

Invoke-Command -ComputerName ADomainController -ScriptBlock {Get-Aduser -Filter “some limiting filter” 

Look at the list of users. Now run the same command


Invoke-Command -ComputerName NotADC  -ScriptBlock {Get-Aduser -Filter “some limiting filter” 

You won’t see the users. That’s because the second hop to the dc. Or you can just do a dir on a remote share over income-command and see Access Denied

If it was just a ps1 file, you could do it this way without copying it.

Invoke-Command -ComputerName Host2 -FilePath \\Host3\share\some.ps1

and it would execute it fine. Now remember anything inside that script that tries to then connect to another host will be subject to the double hop issue and you’ll have to decide how to handle those.