-2

I have the following script powershell command but it returns access denied. I assume the Error 1603 is caused by remote accessing the server. However, the $username has admin rights in the computer01 server.

To recheck if my hunch was right, I tried to test with the following and I got access denied:

Start-Process cmd -Credential $Cred

Update

The error was due to the $Cred . Removing the -Credential argument works fine.

End of Update

The commands have no problems executing directly in the computer01 machine using the cmd.exe.

I want to use cmd /c in this case as I need to get the real exit code from the SETUP.EXE installer.

See full script below:

$script = {
    #Param( 
    #   [String]$username,
    #   [String]$password
    #)

    # $Cred = New-Object System.Management.Automation.PSCredential ($username, $password)
$respfile = "$env:TEMP\test.resp"


echo 'key=value' > $respfile

$username = "$env:USERDOMAIN\$env:USERNAME"
Write-Host Hello $username


$Creds = (Get-Credential -Credential "$env:USERDOMAIN\$env:USERNAME" )

        Start-Process cmd -Credential $Creds

#This command cannot be run due to the error: Access is denied.
#    + CategoryInfo          : InvalidOperation: (:) [Start-Process], #InvalidOperationException
#    + FullyQualifiedErrorId : #InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand
#    + PSComputerName        : computer01
    
        # cmd /c "$path\SETUP.EXE /INSTALL -s /RESPFILE:'$respfile'"
        runas /user:$Username "SETUP.EXE" /INSTALL -s /RESPFILE:"$respfile"
        echo $LASTEXITCODE
# Error 1603
        
}

#$username = 'domain/user'
#$password = 'password'
$server = 'computer01'

$Creds = New-Object System.Management.Automation.PSCredential 

$session = New-PSSession -ComputerName $server
#Invoke-Command -Session $session -Scriptblock $script -Argumentlist $username, $password
Invoke-Command -Session $session -Scriptblock $script -Credential $Creds #updated based on @postanote advise

Remove-PSSession -ComputerName $server

I have found the following similar link install-remotely but do not want to use the ENTER-PSSession command. I do not want to exit the current PSSession and remotely join again in server just to install then exit.

Any suggestions how to use only PSSession and successfully executing installers in the remote server?

emyatsuna
  • 41
  • 7
  • Hi, Thanks for the information.I did execute using the Start-Process prior to cmd with the script `Start-Process 'cmd' -Verb Runas -ArgumentList "$path\SETUP.EXE /INSTALL -s /RESPFILE:'$respfile'"` but the `setup.exe` file didn't execute. If it's just the command `Start-Process setup.exe` then it'll run but adding the additional args in the line, it won't. I just need to execute the exe file with the exact arguments that is running in `cmd`. – emyatsuna Jul 30 '20 at 13:07
  • 1
    There are many ways to run exes with docs all over the web on the topic and the one from Microsoft. [PowerShell: Running Executables]( https://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx) – postanote Jul 30 '20 at 22:17
  • thanks @postanote I have tried all the samples in the link you've provided. I'm not sure but I think the access denied error was caused by installating exe remotely using pssession. I've updated my question here. – emyatsuna Aug 08 '20 at 13:09

3 Answers3

0

As one mentioned in the comments, you don't need cmd.exe. You can use the call/invocation operator - & - to specify that the next token on the line is a command:

& "$path\SETUP.EXE" /INSTALL -s /RESPFILE:$respfile

Of course, for this to work, the parameters to SETUP.EXE need to be correct (I don't know whether that's the case or not).

Bill_Stewart
  • 22,916
  • 4
  • 51
  • 62
  • Hi @Bill_Stewart yes, thanks! However, I forgot to mention that I am executing it remotely. I wonder if that's causing the error. I have updated my question to make it clearer. – emyatsuna Aug 08 '20 at 13:11
0

Never pass plain text passwords in scripts. It exposes you to uneeded risks. Use proper secured credentials models.

Working with Passwords, Secure Strings and Credentials in Windows PowerShell

quickly-and-securely-storing-your-credentials-powershell

PowerShell remoting requires the use of an implicit (New-PSSession) or explicit (Enter-PSSession) session.

About Remote Requirements

There are only a handful of cmdlets you can use as non-Admin ir run without PSRemoting enabled.

Tip: Work Remotely with Windows PowerShell without using Remoting or WinRM

As noted in the Powershell Help file | MS Docs link above, with PSRemoting, you must be using an account that is an admin on the remote host.

In Windows OS proper, to install software, you must be an admin and running that in an admin session.

PowerShell runs in the context of the user who started it.

If you are trying to run in another user context, that is a Windows Security boundary, and you cannot do that without PowerShell natively, you'd need other tools like MS Sysinternals PSExec. See also:

Find-Module -Name '*Invoke*' | Format-Table -AutoSize
# Results
<#
Version     Name                                 Repository Description                                                                                        
-------     ----                                 ---------- -----------                                                                                        
...                                                         
3.1.6       Invoke-CommandAs                     PSGallery  Invoke Command as System/User on Local/Remote computer using ScheduleTask.                         
...
#>

Try this refactored option...

$script = {
    $Creds = (Get-Credential -Credential "$env:USERDOMAIN\$env:USERNAME" )
    
    $respfile = 'whatever this is'     
    & "SETUP.EXE /INSTALL -s /RESPFILE:'$respfile'"
    Write-Output $LASTEXITCODE
}

$server   = 'computer01'
$session  = New-PSSession -ComputerName $server
Invoke-Command -Session $session -Scriptblock $script -Credential $Creds

Remove-PSSession -ComputerName $server

Details

# Get specifics for a module, cmdlet, or function
(Get-Command -Name Invoke-Command).Parameters
(Get-Command -Name Invoke-Command).Parameters.Keys
Get-help -Name Invoke-Command -Examples

# Results
<#
Invoke-Command -ComputerName server01 -Credential domain01\user01 -ScriptBlock {Get-Culture}
$s = New-PSSession -ComputerName Server02 -Credential Domain01\User01
$LiveCred = Get-Credential
Invoke-Command -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.exchangelabs.com/PowerShell -Credential $LiveCred -Authentication Basic 
Invoke-Command -Session $s -ScriptBlock { Get-HotFix } -SessionOption $so -Credential server01\user01
Enable-WSManCredSSP -Delegate Server02
Set-Item WSMan:\Server02*\Service\Auth\CredSSP -Value $True
Invoke-Command -Session $s -ScriptBlock {Get-Item \\Net03\Scripts\LogFiles.ps1} -Authentication CredSSP -Credential Domain01\Admin01
#>
Get-help -Name Invoke-Command -Full
Get-help -Name Invoke-Command -Online
postanote
  • 15,138
  • 2
  • 14
  • 25
  • Yes, you are correct. Passing plaintext passwords are risky. Thanks for updating @postanote . I wonder if we should put **2** `$Creds` in here. 1 as creds for logging in the remote and the other is for executing the script? I used a login credentials with **Admin access rights** in the remote computer but still getting `1603`. – emyatsuna Aug 10 '20 at 03:05
  • Tried run as admin by executing the following script but still getting access denied. All other PS simple commands like `Write-Host Test` works but not with executable files. I wonder what it is that I may have missed. `$username = "$env:USERDOMAIN\$env:USERNAME"` `runas /user:$username "SETUP.EXE" /INSTALL -s /RESPFILE:"$respfile"` – emyatsuna Aug 10 '20 at 03:10
  • Get-Credential will only take one credential set. [To use multiple credentials, then you need to store that in a secure file and call from there as needed](https://www.jaapbrasser.com/quickly-and-securely-storing-your-credentials-powershell/), but that file has to be made available. At this point. I suggest you create a Scheduled Task with than needed creds on the remote host. Set it to run once, or at logon or at a particular time. – postanote Aug 10 '20 at 05:01
  • Okay thanks. I'll try that. However, I don't really need to store my creds in secure file tho. I only need the creds to connect to remote host. The creds has admin rights in remote host so I assumed that the user creds that I used can execute `exe` files in the remote host anytime but causing error 1603 - access denied. – emyatsuna Aug 10 '20 at 05:39
0

So, I was able to solve my problem.

1603 is the error thrown by the setup.exe.

Just to be sure, I manually executed first the following directly in the server using CMD and it was working!

$path\SETUP.EXE /INSTALL -s /RESPFILE:'$respfile'

I did a lot of testings. Researched and as mentioned from comments above, I did different ways to execute programs using powershell. I even used ACL to change ownership of installer directory/ files, switching to different user accounts (with different priviledges) but still getting access denied (including the Admin account).

It took days before I realized the difference in output file size of manual run in machine and the remote. The cause was the $respfile. It really is worth checking every possible reason/ scenario why there's access denied. Plus I cannot extract the setup.exe and its contents to troubleshoot.

The $respfile was created via powershell. I noticed the size created by powershell is doubled compared to a CMD size that was needed. With that, I assumed that the setup.exe reads file in UTF-8 format. I only know that it's working when triggered via CMD and not via powershell.

I suddenly bumped on this links differrent Powershell and CMD sizes and convert file content to CMD readable file - utf8. After converting the $respfile to UTF-8 format, I was able to run the exe successfully.

Hopefully, this can help others too!

emyatsuna
  • 41
  • 7