Start process with path space - powershell

I'm having trouble with path spacing. This works:
$mediaPath = 'C:\Scripts'
$installerPath = Join-Path $mediaPath -ChildPath 'test.msi'
Start-Process -FilePath msiexec.exe -ArgumentList "/i $installerPath /quiet" -Wait -NoNewWindow
This does not:
$mediaPath = 'C:\Scripts\Directory with a space\foo'
How to handle spaces in the path when passing arguments to Start-Process?

You're passing the arguments improperly.
$media = 'C:\Scripts\test.msi'
Start-Process -FilePath msiexec -ArgumentList #('/i',"`"$media`"",'/quiet') -Wait -NoNewWindow

Related

Install Chrome on Windows with a .bat file using PowerShell

I was searching around and found a few hints but a few detail pieces are missing.
Here is what I have:
install-chrome.bat
PowerShell -NoProfile -Command "&{Start-Process PowerShell -ArgumentList '-NoProfile -File install-chrome.ps1' -Verb RunAs}"
install-chrome.ps1
$client = New-Object System.Net.WebClient;
$client.DownloadFile("https://dl.google.com/chrome/install/ChromeStandaloneSetup64.exe", ".\ChromeStandaloneSetup64.exe");
.\ChromeStandaloneSetup64.exe /silent /install ;
Two things are not working as expected:
I still get a UAC popup even though the posts I found state that the above should start PowerShell in Admin mode.
I was expecting .\ would download the .exe to the directory the .ps1 and .bat scripts are located.
Any hints on how to solve this?
EDIT:
Thanks to the reply from #TheIncorrigible1 I managed to solve the second part. Both options work more or less (it downloads it, but the installation throws an error locally) when I execute them directly in PowerShell:
< V3
$PSScriptRoot = Split-Path -Parent -Path $script:MyInvocation.MyCommand.Path
$uri = "https://dl.google.com/chrome/install/ChromeStandaloneSetup64.exe"
$path = "$PSScriptRoot\ChromeStandaloneSetup64.exe"
$client = New-Object System.Net.WebClient
$client.DownloadFile($uri, $path)
& $path /install
V3+
$uri = "https://dl.google.com/chrome/install/ChromeStandaloneSetup64.exe"
$path = "$PSScriptRoot\ChromeStandaloneSetup64.exe"
Invoke-WebRequest -Uri $uri -OutFile $path
& $path /install
But the batch still throws errors:
At line:1 char:62
+ ... tart-Process PowerShell -Verb RunAs -ArgumentList -NoProfile, -File, ...
+ ~
Missing argument in parameter list.
At line:1 char:69
+ ... ocess PowerShell -Verb RunAs -ArgumentList -NoProfile, -File, 'C:\Pro ...
+ ~
Missing argument in parameter list.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingArgument
Two things-
You don't need to wrap your batch command to powershell in a scriptblock and -ArgumentList expects an array of string arguments:
powershell.exe -NoProfile -Command "Start-Process -FilePath powershell.exe -ArgumentList #('-NoProfile', '-File', '%~dp0install-chrome.ps1') -Verb RunAs"
There's an automatic variable, $PSScriptRoot, to determine where your root directory is:
$uri = 'https://dl.google.com/chrome/install/ChromeStandaloneSetup64.exe'
if (-not $PSScriptRoot) {
$PSScriptRoot = Split-Path -Parent -Path $script:MyInvocation.MyCommand.Definition
}
$outFile = "$PSScriptRoot\ChromeStandaloneSetup64.exe"
if ($PSVersionTable.PSVersion.Major -lt 3) {
(New-Object -TypeName System.Net.WebClient).DownloadFile($uri, $outFile)
}
else {
Invoke-WebRequest -Uri $uri -OutFile $outFile
}
& $outFile /silent /install
Here you go:
$Path = $env:TEMP; $Installer = "chrome_installer.exe"; Invoke-WebRequest "http://dl.google.com/chrome/install/375.126/chrome_installer.exe" -OutFile $Path\$Installer; Start-Process -FilePath $Path\$Installer -Args "/silent /install" -Verb RunAs -Wait; Remove-Item $Path\$Installer

Calling a Batch File into a Powershell Script

Everytime my Powershellscript is calling the Batchfile, a new Powershell Window opens. How can i modify the script in order to avoid the new window opens? I've tried with -windowstyle hidden and NoNewWindow, but nothing works.
Here is the Batchfile that starts my Powershell Script:
#echo off
set scriptFileName=%~n0
set scriptFolderPath=%~dp0
set powershellScriptFileName=test.ps1
powershell.exe -windowstyle hidden -Command "Start-Process powershell \"-ExecutionPolicy Bypass -NoProfile -NoExit -Command `\"cd \`\"C:\Temp\`\"; & \`\".\test.ps1\`\"`\"\" -Verb RunAs"
And here is my Powershell Script:
$Source = "C:\Program Files\Planmeca\Romexis\client\cephmodule\analyses"
$Destination = "\\PRENCIPE-THINK\PDATA\analyses" #<------ UNC PFAD FUER DEN SERVER ANPASSEN!!
New-Item -ItemType directory -Path $Destination -Force
Copy-Item -Path $Source\*.* -Destination $Destination -Force -Recurse
(ROBOCOPY $Source $Destination /MIR /W:30 /R:10)
# Ueberpruefe den Ordner auf veraenderungen
# Fuehre den Script aus bei Aenderung oder Umbennenung
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = 'C:\Program Files\Planmeca\Romexis\client\cephmodule\analyses'
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $false
$watcher.NotifyFilter = [System.IO.NotifyFilters]::LastWrite -bor [System.IO.NotifyFilters]::FileName
while($TRUE){
$result = $watcher.WaitForChanged([System.IO.WatcherChangeTypes]::Changed -bor [System.IO.WatcherChangeTypes]::Renamed -bOr [System.IO.WatcherChangeTypes]::Created, 1000);
if($result.TimedOut){
continue;
}
write-host "Change in " + $result.Name
$A = Start-Process -WindowStyle Hidden -FilePath c:\temp\Bypass.bat -Wait -passthru ;$a.ExitCode
}
Try the '-NoNewWindow' switch. I'm running PS Version 5.1 on Windows 7 and it's available. If you're running an earlier iteration if WMF, you may want to update your machines to 5 or better.

"Open Admin Powershell here" Windows Explorer Context Menu

I wanted to add an item to the windows explorer context menu, that would open a PowerShell as Admin.
I found this command which starts the powershell in the cmd:
PowerShell -windowstyle hidden -Command `"Start-Process cmd -ArgumentList '/s,/k,pushd,%V && PowerShell' -Verb RunAs`"
The problem with this is that the window is the cmd window and not the powershell one.
So I tried to make a command on my own and came up with this:
PowerShell.exe -WindowStyle Hidden -NoExit -Command "Start-Process PowerShell.exe -Verb RunAs -ArgumentList #(`'-NoExit`',`'-Command`',`'Set-Location -LiteralPath `"%V`"`')";
which works fine when executed in the cmd or powershell, but when i put it into the registry (HKEY_CLASSES_ROOT\Directory\shell\PowershellMenu (Administrator)\command\(Default)) the powershell window flashes shortly.
I tried to...
...use the full PowerShell path:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle Hidden -NoExit -Command "Start-Process -FilePath 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' -Verb RunAs -ArgumentList #(`'-NoExit`',`'-Command`',`'Set-Location -LiteralPath `"%V`"`')";
...add a sleep to see if the -NoExit is ignored:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle Hidden -NoExit -Command "Start-Process -FilePath 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' -Verb RunAs -ArgumentList #(`'-NoExit`',`'-Command`',`'Set-Location -LiteralPath `"%V`"; Sleep 10`')";
without any success.
Execute in PowerShell as administrator:
'Directory',
'Directory\Background',
'Drive' | ForEach-Object {
$Path = "Registry::HKEY_CLASSES_ROOT\$_\shell\runas";
New-Item -Path $Path -Name 'command' -Force | Out-Null;
Set-ItemProperty -Path "$Path\command" -Name '(default)' -Value "PowerShell -WindowStyle Maximized -NoExit -NoLogo -Command Set-Location '%V'";
Set-ItemProperty -Path $Path -Name '(default)' -Value 'PowerShell';
Set-ItemProperty -Path $Path -Name 'HasLUAShield' -Value '';
Set-ItemProperty -Path $Path -Name 'Icon' -Value "${Env:WinDir}\System32\WindowsPowerShell\v1.0\powershell.exe,0";
}

Install msi using Start-Process with /q switch?

I want to install an msi with a /q switch, I look online and the examples don't have the /q switch and I keep getting errors.
I need something like:
$WorkingDirectory = (Split-Path $myinvocation.mycommand.path -Parent)
Start-Process -FilePath msiexec /i "$WorkingDirectory\LAPS.x64.msi" -ArgumentList /q
Don't bother with Start-Process. Use the call operator:
& msiexec.exe /i "$WorkingDirectory\LAPS.x64.msi" /q
put the whole command in the brackets
Example(Python msi):
Start-Process msiexec.exe -Wait -ArgumentList "/I $($LocalPython.FullName) /passive ALLUSERS=1 ADDLOCAL=Extensions"
replace /passive with /q
Not all installers are the same. To find the installer switches for your .msi use:
.\LAPS.x64.msi /?
.\LAPS.x64.msi -?
I would also store the msi path in a variable, and use an ArrayList for the arguments, something like this has worked for me in my scripts:
# Path to .msi
$msiPath= 'C:\LAPS.x64.msi'
# Define arguments
[System.Collections.ArrayList]$arguments =
#("/i `"$msiPath`"",
"/quiet")
# Start installation
Start-Process -FilePath msiexec.exe -ArgumentList "$arguments" -Wait -NoNewWindow
$path="C:\Dat\install.msi"
$parameters="/q"
$packageinstall=(split-path $path -leaf) + ' ' + $parameters
write-host $packageinstall
$computers = get-content c:\com.txt
$computers | where{test-connection $_ -quiet -count 1} | ForEach-Object {
copy-item $path "\\$_\c$\windows\temp" -Force -Recurse
$newProc=([WMICLASS]"\\$_\root\cimv2:win32_Process").Create("C:\windows\temp\$packageinstall")
If ($newProc.ReturnValue -eq 0) {
Write-Host $_ $newProc.ProcessId
} else {
write-host $_ Process create failed with $newProc.ReturnValue
}
}

How to capture windows command result from Start-Process?

$features = Start-Process powershell -Verb runAs -ArgumentList "Get-WindowsOptionalFeature –Online"
$features
How can I get the result back into my $feature variable?
Quick & dirty workaround: you can use temporary clixml file to store results of Get-WindowsOptionalFeature cmdlet:
$tempFile = [System.IO.Path]::GetTempFileName()
try
{
Start-Process powershell -Wait -Verb runAs -ArgumentList "-Command Get-WindowsOptionalFeature -Online | Export-Clixml -Path $tempFile"
$features = Import-Clixml -Path $tempFile
# Use $features
}
finally
{
if (Test-Path $tempFile)
{
Remove-Item -Path $tempFile -Force -ErrorAction Ignore
}
}