9
votes

I am getting an error while executing a remote PowerShell script. From my local machine I am running a PowerShell script that uses Invoke-Command to cd into a directory on a remote Amazon Windows Server instance, and a subsequent Invoke-Command to execute script that lives on that server instance. The script on the server is trying to git clone a repository from GitHub. I can successfully do things in the server script like "ls" or even "git --version". However git clone, git pull, etc. result in the following error:

Cloning into 'MyRepo'... + CategoryInfo : NotSpecified: (Cloning into 'MyRepo'...:String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError

This is my first time using PowerShell or a Windows Server. Can anyone provide some direction on this problem.

The client script:

$s = new-pssession -computername $server -credential $user
invoke-command -session $s -scriptblock { cd C:\Repos; ls } 
invoke-command -session $s -scriptblock { param ($repo, $branch) & '.\clone.ps1' -repository $repo -branch $branch} -ArgumentList $repository, $branch
exit-pssession

The server script:

param([string]$repository = "repository", [string]$branch = "branch")
git --version
start-process -FilePath git -ArgumentList ("clone", "-b $branch    https://github.com/MyGithub/$repository.git") -Wait 

I've changed the server script to use start process and it is no longer throwing the exception. It creates the new repository directory and the .git directory but doesn't write any of the files from the github repository. This smells like a permissions issue. Once again invoking the script manually (remote desktop into the amazon box and execute it from powershell) works like a charm.

1
Can you show the lines of script with the Invoke-Command? You should be invoking it with the -Session parameter.Keith Hill
Update: including the scriptsuser204777

1 Answers

11
votes

Anytime you're calling an external executable from PowerShell, I highly recommend using Start-Process. The Start-Process cmdlet handles command line arguments much better, as compared to calling the executables directly.

Important: You must also be aware that if you run two separate Invoke-Command commands (unless you're using the -Session parameter) that you will be operating in two completely distinct PowerShell Remoting sessions! If you use the cd (aka. which is an alias for Set-Location) command, the results of that command will not persist into the new session when you run your Git command.

$GitExe = '{0}\path\to\git.exe' -f $env:SystemDrive;
$ArgumentList = 'clone "c:\path\with spaces\in it"';
Start-Process -FilePath $GitExe -ArgumentList $ArgumentList -Wait -NoNewWindow;

There is also a -WorkingDirectory parameter on the Start-Process cmdlet, that allows you to specify the Working Directory for a process. Instead of using the Set-Location cmdlet to set the "current directory" of the PowerShell session, you're probably better off specifying the full path to the working directory for the process. For example, let's say you had a Git repository in c:\repos\repo01, and your Git exe was in c:\git. You shouldn't worry so much about where PowerShell's "current directory" is, and rather focus on specifying the full paths to:

  1. The Git executable
  2. The Git repositories

Here's an example of how to achieve that:

Start-Process -FilePath c:\git\git.exe -ArgumentList 'clone "c:\repos\repo01" "c:\repos\repo02"" -Wait -NoNewWindow;

Note: I don't know the Git commands, but you should be able to adjust the value of the $ArgumentList variable above, to make it work for you. In PowerShell, you can put double-quotes inside of single-quotes, without having to worry about escaping them.