0

Is there a way to embed an exe to an existing powershell script? My boss wants me to come up with a way to install software on our employees computers that work from home and aren't tech savvy. Essentially, I need to copy a file locally to their computer (which is an exe) and run it from within powershell (or command line) terminal with some arguments (i.e., /norestart /quiet, etc).

5
  • 1
    You could copy the exe to the remote computers (via Copy-Item -ToSession) and then execute them there (via Invoke-Command). Commented Apr 16, 2020 at 19:59
  • Put everything (PS script + EXE) into a self-extracting executable and let them run that. The SFX would extract files to a temp dir and run the PS script. Several ways to do this, e. g. using 7-zip. Commented Apr 16, 2020 at 20:23
  • If the remote employee is on your network (VPN), then using Invoke-Command would be easy. If they are not on your network, then the SFX is probably the best way. Have you ever looked into Microsoft System Center? Commented Apr 16, 2020 at 20:51
  • In Start - Run (Winkey+R) type iexpress for the inbuilt Windows' installer wizard. Commented Apr 17, 2020 at 1:09
  • You have remote access top all these machines. Copy a file to a known directory, set a scheduled task to run it. Commented Apr 17, 2020 at 6:45

1 Answer 1

1

You can use Base64 encoding to embed an exe in a PowerShell script. Run this script to encode the exe. It produces 'base64Decoder.ps1' in the Downloads folder.

# Requires PowerShell 5.1 
# Run this script to encode the exe. 
# It produces 'base64Decoder.ps1' in the Downloads folder. 

$folder = "$env:UserProfile\Downloads\Demo\"
$file = "PowerShell-7.0.0-win-x64.msi"

$option = [System.Base64FormattingOptions]::InsertLineBreaks
$path = Join-Path -Path $folder -ChildPath $file
$bytes = Get-Content $path -Encoding Byte -ReadCount 0

$outputProgram = [System.Text.StringBuilder]::new()

[void]$outputProgram.AppendLine( '$encodedText = @"' )
[void]$outputProgram.AppendLine( ([Convert]::ToBase64String($bytes, $option)) )
[void]$outputProgram.AppendLine( '"@' )
[void]$outputProgram.Append(
@"

`$downloads = Join-Path -Path `$Env:USERPROFILE -ChildPath "Downloads"
`$file = "$file"
`$path = Join-Path -Path `$downloads -ChildPath `$file
`$value = [System.Convert]::FromBase64String(`$encodedText)

Set-Content -Path `$path -Value `$value -Encoding Byte
"@
)

$downloads = Join-Path -Path $Env:USERPROFILE -ChildPath "Downloads"
$outFile = "base64Decoder.ps1"
$outPath = Join-Path -Path $downloads -ChildPath $outFile

Set-Content -Path $outPath -Value ($outputProgram.ToString())

You can copy and paste the contents of base64Decoder.ps1 into an existing PowerShell script to embed the exe. Or, if too large, include base64Decoder.ps1 with the original script and invoke it when necessary.

Run the script on the target computer to reproduce the original file in the Downloads folder. This is valid PowerShell syntax and can be included in a script.

& "$env:UserProfile\Downloads\base64Decoder.ps1"

You might have to set the execution policy before the script will run.

Set-ExecutionPolicy RemoteSigned

Invoke the exe with Start-Process. This can be saved in a script.

Start-Process -FilePath "$env:UserProfile\Downloads\PowerShell-7.0.0-win-x64.msi" -ArgumentList '/? '

If you want to send a PowerShell script via E-mail, attach it as .txt and have them rename it. I'm sure you know that file attachments are generally limited to 10MB.

If the exe is available online, you can use Invoke-WebRequest which is much easier.

Invoke-WebRequest "https://github.com/PowerShell/PowerShell/releases/download/v7.0.0/PowerShell-7.0.0-win-x64.msi" -outfile "$env:UserProfile\Downloads\PowerShell-7.0.0-win-x64.msi"

You can test these steps in Windows Sandbox.

While this is the technically correct answer to your question, I don't recommend it.

First, it is more complicated than simply downloading an installer from the Internet and using (the MSI) switches on it.

Second, the performance of my script is poor for nontrivial exe's. And it will create more problems than it solves.

I'm not sure what the assumption is here. But if these computers are not managed, I imagine there will be a support request for each install. What you won't be able to do is just E-mail this script to 100 people or put it in a logon script and walk away. That would be very bad. Even if this were in the office, I would not deploy an unattended install without thorough testing. And that's assuming local storage and a logon script or equivalent: not people working from home as a one-off.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.