Elevating PowerShell script permissions - powershell

I am trying to run script to manage some VHD Disks, but the disk mount is failing due to elevated permissions required. The user the script is run under is a local admin, but UAC is blocking it I think. The error which comes back is: “DiskState=Failed to mount disk - "Access to a CIM resource was not available to the client”
Ideally I need to the script to run under elevated command prompt automatically. Any idea's how I can achieve that programmatically?
The script I am running is this:
$location = "C:\temp"
$name = "downloadfile"
$Author = "FSLogix"
$FilePath = "Filepath here"
$LogFilePath = "Logfilepath here"
# Force to create a zip file
$ZipFile = "$location\$Name.zip"
New-Item $ZipFile -ItemType File -Force
$RepositoryZipUrl = "https://github.com/FSLogix/Invoke-FslShrinkDisk/archive/master.zip"
# download the zip
Write-Host 'Starting downloading the GitHub Repository'
Invoke-RestMethod -Uri $RepositoryZipUrl -OutFile $ZipFile
Write-Host 'Download finished'
#Extract Zip File
Write-Host 'Starting unzipping the GitHub Repository locally'
Expand-Archive -Path $ZipFile -DestinationPath $location -Force
Write-Host 'Unzip finished'
# remove the zip file
Remove-Item -Path $ZipFile -Force
# Run the FSLogix Optimisation
C:\temp\Invoke-FslShrinkDisk-master\Invoke-FslShrinkDisk.ps1 -Path $FilePath -Recurse -PassThru -LogFilePath $LogFilePath\logfile.csv

You can elevate the PS script using the Powershell as a separate process and make it "run as admin" like below:
start-process PowerShell -verb runas
OR
Powershell -Command "Start-Process PowerShell -Verb RunAs"
Apart from that , you can condition it as well. There is a beautiful conditional code shared by PGK which can help as well:
if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{
$arguments = "& '" +$myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
}

Related

PowerShell Start-Process Not Starting when script called remotely

I am trying to remotely install Octopus Deploy Tentacle to a VM. I have a powershell script that I've written that handles this business for me. It works exactly as expected when I am physically logged into the machine, but when I am remotely executing it on the machine it doesn't run the installer. Every other part of the script works fine though.
The portion of the script that downloads and installs:
try{
$url = "https://octopus.com/downloads/latest/OctopusTentacle64"
$downloadPath = "$env:TEMP\octopus\"
if (Test-Path $downloadPath) {
Remove-Item -Path $downloadPath -Recurse -Force
}
New-Item -Type Directory -Path $downloadPath | Out-Null
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
(New-Object System.Net.WebClient).DownloadFile($url, "$downloadPath\Octopus.Tentacle.msi")
Start-Process -FilePath "$downloadPath\Octopus.Tentacle.msi" -ArgumentList "/passive" -Wait -verbose
Write-Output "Octopus Tentacle Installed."
} catch { throw "error downloading tentacle. try again later."}
I am using this to attempt to run the file remotely(edit, copied wrong line):
Invoke-Command -ComputerName $vmName -FilePath "\\$vmName\Installers\Install-Calamari.ps1" -Credential $creds -ArgumentList $deployTag, $envID
What am I missing?

can't using Start-Process powershell.exe run a ps1 file at onedrive path

I have a ps1 file in Onedrive for Business path. when running below command, it gets something wrong, but it runs so fast, I can't get the error screenshots.
If I put the script in another local drive path, it works fine.
Any prevention in Onedrive?
Start-Process powershell.exe -ArgumentList $ps1path
ps file content
$current_path = Split-Path -Parent $MyInvocation.MyCommand.Definition
$up1_path = Split-Path -Parent $current_path
$up2_path = Split-Path -Parent $up1_path
$up1_path
$up2_path
cmd /c "pause"
It's not Onedrive case. Just the start-process can't accept a space in ArgumentList.
$pspath = $pspath -replace ' ','` '
Start-Process powershell.exe -ArgumentList $pspath

execute a script from a created folder with Powershell

In powershell i can download a script in a specific random name created folder but i cannot find the right way to execute the script from there.Here the code that i used:
$uuid=(Get-WmiObject Win32_ComputerSystemProduct).UUID;
$path = $env:appdata+'\'+$uuid; $h=$path+'\d';
if(!(test-path $path)) { New-Item -ItemType Directory -Force -Path
$path;};
Invoke-WebRequest mywebsitefordownloadingscript -OutFile $path\\test.txt;
start-process -Windowstyle hidden cmd '/C
'powershell.exe' -exec bypass $path\\test.txt';
there was something missing in last string maybe the problem persist if i use '+$path+' too.
Any suggestions??
The problem is your single quotes on the last two lines. Since you have enclosed $path within single quotes it is not expanded and is taken literally. Change to double quotes to expand the variable, and this should work.
$uuid=(Get-WmiObject Win32_ComputerSystemProduct).UUID
$path = $env:appdata+'\'+$uuid
$h=$path+'\d'
if(!(test-path $path)) {
New-Item -ItemType Directory -Force -Path $path
}
Invoke-WebRequest mywebsitefordownloadingscript -OutFile $path\\test.txt
start-process -Windowstyle hidden cmd "/C 'powershell.exe' -exec bypass $path\\test.txt"

How to Run script with admin rights to change execution policy

See below script:
I need to launch this script with admin rights embedded inside of the script to set execution policy to unrestricted and then at the end of the script set it back. From what I've found so far this is either not possible or very difficult to do. I'm hoping there is an easier way to do this. The users that will be running this script do not have admin rights on their PC's so they will not be able to elevate and manually run from inside of powershell.
Stop-process -Name OUTLOOK -ErrorAction SilentlyContinue -Force
Stop-process -Name communicator -ErrorAction SilentlyContinue -Force
Stop-process -Name lync -ErrorAction SilentlyContinue -Force
Stop-Process -Name UcMapi -ErrorAction SilentlyContinue -Force
Stop-Process -Name skypehost -ErrorAction SilentlyContinue -Force
Stop-Process -Name searchprotocolhost -ErrorAction SilentlyContinue -Force
$OstPath = "c:\users\$([environment]::username)"+ "\AppData" + "\local" + "\Microsoft" + "\Outlook"
$ost = get-ChildItem $OstPath | where { $_.Extension -eq ".ost"}
$ost | remove-Item -force
Start-Process Outlook
if (Test-Path 'C:\Program Files (x86)\Microsoft Office\office15\lync.exe')
{
Start-Process 'C:\Program Files (x86)\Microsoft Office\office15\lync.exe'
}
Else
{
write-host "Lync is not installed"
if (Test-Path 'C:\Program Files (x86)\Microsoft Office Communicator')
{
Start-Process 'C:\Program Files (x86)\Microsoft Office Communicator\communicator.exe'
}
Else
{
write-host "Communicator is not installed"
}
}
You can use:
$GBL_Username = "Here type your username"
$GBL_Password = ConvertTo-SecureString –String "Here type your password in plain text" –AsPlainText -Force
$GBL_Credential = New-Object –TypeName System.Management.Automation.PSCredential –ArgumentList $GBL_Username, $GBL_Password
Start-Process 'C:\Program Files (x86)\Microsoft Office\office15\lync.exe' -Credential $GBL_Credential
And use the variable $GBL_Credential with the second part (the execution of Office Comunicator)
A problem with this: the credential will show in plain text and, if someone try to edit the script with notepad, PowerShell ISE or other program, they can will see the passsword.
Have a good day.
From what I see in the script, there's no need to elevate. If this is only to overcome the ExecutionPolicy than your approach is wrong. ExecutionPolicy is there to prevent users run untrusted scripts. So far your script is one of those.
Correct way of doing it would be to sign your script with the certificate and set your ExecutionPolicy to Allsigned on all computers. Users will then only be able to run the signed scripts from now on.
If this is not possible, I see 2 options:
Users copy contents of the script and paste it into the powershell window
You set ExecutionPolicy to unrestricted. Keep in mind that users will still need to elevate if they try to do something serious, but for this script elevation is not necessary.
So all in all, ExecutionPolicy is there to prevent exactly what you are trying to do, so do not expect it will be easy to overcome. It's also not something that you turn off and on. You should think of what is acceptable for you and set it to appropriate level in your environment.

NSIS Script Wrap to PS1 into EXE and Run as Admin

I have the following NSIS (.nsi) script that wraps PowerShell script into exe.
In addition, I would like the exe to run as admin because the scripts needs to update registry key.
NSIS Script is:
!include x64.nsh
RequestExecutionLevel admin ;Require admin rights on NT6+ (When UAC is turned on)
OutFile "file.exe"
SilentInstall silent
Section
SetOutPath $EXEDIR
File "file.ps1"
# Run the script to update
ExecWait "powershell -ExecutionPolicy Bypass -WindowStyle Hidden -File .\file.ps1"
SectionEnd
Function .onInstSuccess
Delete "file.ps1"
FunctionEnd
PowerShell script is:
$registryPath = "HKLM:\SOFTWARE\Test"
$Name = "keyName"
$value = "keyValue"
$preRegVer = (Get-ItemProperty $registryPath).Version
#log "Pre registry value: $preRegVer"
If(!(Test-Path $registryPath))
{
# log "Path does not exist"
New-Item -Path $registryPath -Force | Out-Null
# log "Path created"
New-ItemProperty -Path $registryPath -Name $name -Value $value -PropertyType String -Force | Out-Null
# log "Value created"
}
Else {
# log "Path exist"
$val = Get-ItemProperty -Path $registryPath
if($val.Version -eq $null)
{
# log "Value does not exist"
New-ItemProperty -Path $registryPath -Name $name -Value $value -PropertyType String -Force | Out-Null
# log "Value created"
}
Else {
# log "Value exist"
Remove-ItemProperty -path $registryPath -Name Version -Force
# log "Value removed"
New-ItemProperty -Path $registryPath -Name $name -Value $value -PropertyType String -Force | Out-Null
# log "Value created"
}
}
When I run .exe file, it asks for elevated permission, but does not update the key.
I know that powershell script works, because I used PowerGUI to compile it to exe, and it updates the key.
Only problem with PowerGUI is that it does not have an option to run as Admin.
I am suspecting you're running on 64bit machine and there is conflict with bitness.
Haven't tried this, but try this ans see if that works.
${If} ${RunningX64}
${DisableX64FSRedirection}
${EndIf}
ExecWait "powershell -ExecutionPolicy Bypass -WindowStyle Hidden -File .\file.ps1"
${If} ${RunningX64}
${EnableX64FSRedirection}
${EndIf}
Instead of using power shell script, you can perform same task in NSIS itself. You can modify and you can create your own new registry entry using nsis.
for example you can use following commands to write and read the registry
WriteRegStr HKLM SOFTWARE\NSIS_Example2 "Version" "1.0"
ReadRegStr $mm HKLM "SOFTWARE\NSIS_Example2" "Version"
Here's a link!
The end result of our build process calls NSIS to create an executable for the product(s) we're building. We too are trying to call Powershell similar to the example listed above to run at deploy time, the powershell script is called to manage special duties on the server that are related to IIS.
In the NSIS file we've tried the variations below with no success:
nsExec::ExecToStack 'powershell -inputformat none -ExecutionPolicy bypass -File "C:\HardCodedLocation_Instance.ps1" '
nsExec::ExecToStack 'powershell.exe "& "C:\HardCodedLocation_Instance.ps1"' $0
ExecWait 'powershell -ExecutionPolicy Bypass -WindowStyle Hidden -File C:\HardCodedLocation_Instance.ps1' $0
${PowerShellExec} "C:\HardCodedLocation_Instance.ps1"
The "C:\HardCodedLocation_Instance.ps1" is getting run by NSIS at deploy time but the tasks that require administrative permissions in the script are not being completed.
The first two lines in "C:\HardCodedLocation_Instance.ps1":
Set-ExecutionPolicy -ExecutionPolicy Bypass
Import-Module webadministration
I'm running the executable logged onto a server as an administrator. I can then turn around, right click on "C:\HardCodedLocation_Instance.ps1" and "Run with PowerShell" and it works as it should.