Powershell Script Wrapper for Running as Admin - powershell

I am writing a script to deploy through group policy. The script deletes a number of registry settings to fix an issue we have on our build of Windows. The script needs to run as an administrator as the keys exist in hives that require admin rights to delete.
Because GP runs powershell scripts as the logged on user, I am looking at creating a wrapper which will read an encrypted password for the local user account and then run the script with it.
My script is able to read the credential, but I am getting errors when running the start-process command. If I try and reference the script it will give the error that the path doesn't exist, even though you can dump the contents using cat .
I then tried reading it into a variable and running powershell with the -command argument. If I do this I get an error.
"Start-Process : This command cannot be run due to the error: The parameter is incorrect"
I understand that I need to enclose the code in braces, but I am not sure how this is done as concatenating them to the string doesn't work.
if($connected) {
$Encrypted = Get-Content <PATH TO PASSWORD FILE>
$pass = ConvertTo-SecureString -String $Encrypted -Key (1..16)
$user = <MY ADMIN ACCOUNT>
$Credential = New-Object System.Management.Automation.PSCredential $user, $pass
echo $(pwd)
echo $(cat <PATH TO SCRIPT>)
$code = $( cat <PATH TO SCRIPT> )
#Invoke-Command -ScriptBlock {$code} -Credential $Credential
#Start-Process powershell.exe <PATH TO SCRIPT> -Credential $Credential
Start-Process powershell.exe -ArgumentList "-command $code" -Credential $Credential
}
I just need a way of executing the code in my second script, but I can't work out how to do this as it's not behaving as expected. Sorry, as I am sure I am missing something obvious.

Related

SSH Connection & Commands using PLINK with Powershell

I'm trying to create a simple script which run a command and send the output to a variable.
this is the script:
$output = &"<Path to PLINK>\PLINK.exe" -ssh <username>#<IP Address> -pw <password> "my command"
the thing is the command im running is like "top" in linux - a task manager which won't quit until enter is being pressed.
how can i take the CLI output from that situation without touching my keyboard?
i wrote an automation with opening cmd and sending "keys" function inorder to get what i want but i cannot get the output from the CLI by doing so. (also i dont beleive its the right way.)
Thanks in advance.
As I saw in the following page:
Run As Admin
using the following code will run the programm PLINK.EXE for you.
$Username = 'Username'
$Password = 'Password'
$SecurePassword = ConvertTo-SecureString $Password -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential ($Username,$SecurePassword)
Start-Process powershell.exe -Credential $Credential -NoNewWindow -ArgumentList "(Start-Process -FilePath '\\some\path\app.exe' -ArgumentList '/q).ExitCode"
I solved my issue by installing POSH-SSH module for Powershell.

Invoke-AzVMRunCommand and Start-Process under specific user on remote VM using Azure Runbook

I need to run Start-Process on a remote VM with specific user account using Azure Powershell Runbook
function Install-Postgres {
$username = "aact-import-vm1\aact-importer"
$password = "ChangeMe!"
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList `
#($username,(ConvertTo-SecureString -String $password -AsPlainText -Force))
write-output $cred
# run pg installer
Start-Process "C:\Program Files\WindowsPowerShell\Modules\Install-Postgres\postgresql.exe" -ArgumentList `
"--mode unattended", "--unattendedmodeui none",`
"--prefix `"C:\Program Files\PostgreSQL\10`"", "--datadir `"C:\Program Files\PostgreSQL\10\data`"",
"--superpassword `"ChangeMe!`"",`
"--servicename `"postgres`"", "--serviceaccount `"postgres`"", "--servicepassword `"ChangeMe!`""`
-Wait -Credential $cred;
}
$script = Get-Content Function:\Install-Postgres
Out-File -FilePath Install.ps1 -InputObject $script
#Note that the -ScriptPath should not point to the remote path(in remote vm), it should point to the local path where you execute the command Invoke-AzureRmVMRunCommand
$output = Invoke-AzVMRunCommand -ResourceGroupName $resourceGroupName -Name $vmName -CommandId 'RunPowerShellScript' -ScriptPath Install.ps1
write-output $output.Value
#after execution, you can remove the file
Remove-Item -Path Install.ps1
The script above produces the following error:
Start-Process : This command cannot be run due to the error: Access is denied.
If I run the script above without specific credentials the postgres installer produces this error in the log:
Executing icacls "C:\Windows\Temp/postgresql_installer_1ef9b3f2c6" /T /Q /grant "WORKGROUP\aact-import-vm1$:(OI)(CI)F"
Script exit code: 1332
Script output:
Successfully processed 0 files; Failed processing 1 files
Script stderr:
WORKGROUP\aact-import-vm1**$**: No mapping between account names and security IDs was done.
Please notice that there is symbol $ instead of user name.
However, if I run it on the VM it works fine and produces this line in the log:
Executing icacls "C:\Users\aact-importer\AppData\Local\Temp\2/postgresql_installer_2662c862ff" /T /Q /grant "aact-import-vm1\aact-importer:(OI)(CI)F"
Script exit code: 0
As far as I can see, If I run runbook script remotely without credentials it runs under NTAUTHORITY\SYSTEM that's why there is symbol $ instead of user name in the postgres installer log. If I run it locally it uses proper user and everything works fine.
The question is: how can I specify a user account to run Start-Process on the remote VM?
Same question on msdn https://social.msdn.microsoft.com/Forums/en-US/a7fa0ca8-5cba-42bb-8076-9a8d4a654beb/invokeazvmruncommand-and-startprocess-under-specific-user-on-remote-vm-using-azure-runbook?forum=azureautomation#a7fa0ca8-5cba-42bb-8076-9a8d4a654beb
For those who are interested:
After investigation with MS support they confirmed that runbook (not hybrid) always runs under NTAUTHORITY\SYSTEM

Start-Process powershell credentials don't work but when using cmd it does

I am trying to run a powershell script from another powershell script passing in the credentials of a different user and then using the credentials:
Start-Process powershell.exe -Credential "LON\my-user" -NoNewWindow -ArgumentList "-file C:\DevopsScripts\stuckApps.ps1"
I have this is numerous different ways all get the same error. I have tried setting the username and password before the command:
$username = "LON\my-user"
$password = "pass"
$PSS = ConvertTo-SecureString $password -AsPlainText -Force
$cred = new-object system.management.automation.PSCredential $username,$PSS
$env:USERNAME
Start-Process powershell.exe -Credential $cred -NoNewWindow -ArgumentList "-file C:\DevopsScripts\stuckApps.ps1"
But everything I try gets the error:
Start-Process : This command cannot be run due to the error: The user name or password is incorrect.
I know the username and password are correct as they have been tested on the cmd which it works fine:
C:\Users\ADM-me>runas /noprofile /user:LON\my-user"powershell.exe C:\DevopsScripts\stuckApps.ps1"
What am I doing wrong here and how could I fix this, preferably by setting the password beforehand, so this can be automated. Also this does not need to be done using Start-Process, just this is the closest thing I could find to working.
I think the problem I am having is this, in stuck apps it has this:
$conn = New-Object System.Data.SqlClient.SqlConnection
$conn.ConnectionString = "Server = mssql.co.uk; Database = mydata; Integrated Security = true;"
$conn.Open()
I need this to run the credentials that I am trying to pass through it or else I get this error.
`Exception calling "Open" with "0" argument(s): "Login failed. The login is from an untrusted domain and cannot be used with Windows authentication."
But I can't pass the credentials through as the only ones that work are admin ones, (which I have but then that will throw the error above). Is it possible for me to use the admin logins to access stuck apps then use the logins needed to connect on stuck apps as an AD login.
Your first attempt with -Credential "LON\my-user" can't work, but your second attempt is correct, building the object of class PSCredential, as required (see the type in Get-Help Start-Process -Parameter Credential, it is PSCredential and not String). I tried the same with some reused code here, and it works here both or CMD and PS1 calling a PS1 test script via Powershell.exe, using a local test account (sorry, no domain #home).
So even though my code ist not identical and the domain of the user is the local machine, the approach is the same compared to yours and - sorry that this does not solve your problem - I don't see that you are doing sth. wrong.
To play safe, please make sure though to test with the same Powershell version, the below scripts executed under W10 1607 (so Powershell 5.1.14393.1198), all scripts in the same directory.
testscript.ps1
write-host "Testscript is run with user: $($env:USERNAME)"
Start-Sleep 2
testrun.cmd
runas /noprofile /user:%COMPUTERNAME%\myaccount "powershell.exe -NoProfile -ExecutionPolicy ByPass -file %~dp0testscript.ps1"
testrun.ps1
$Username = "$($env:COMPUTERNAME)\myaccount"
$Password = 'mypassword'
$SecurePassword = ConvertTo-SecureString -String $Password -AsPlainText -Force
$ScriptFile = Join-Path -Path $PSScriptRoot -ChildPath 'testscript.ps1'
$Credential = New-Object System.Management.Automation.PSCredential( $Username, $SecurePassword)
$StartOpts = #{ 'FilePath' = 'powershell.exe'
'Credential' = $Credential
'NoNewWindow' = $false
'ArgumentList' = #( '-f', $ScriptFile,
'-ExecutionPolicy', 'Bypass',
'-NoProfile'
)
}
Start-Process #StartOpts
Some remarks on testrun.ps1
Don't mind the parameters for Start-Process being passed as a hashtable, it's just better readable for me, otherwise it makes not difference
The ArgumentList is being passed as a string array here - I prefer it this way so that it is automatically taken care for double qouting parameters, e.g. when the pathname of the script directory would contain spaces
The parameter -NoNewWindow passed to Start-Process seems not to have any effect here - a new window is opened
I always recommend to add the parameters -Noprofile and -ExecutionPolicy Bypass when using Powershell.exe to launch scripts or execute commands, just to make sure it works despite of the Execution Policy set or any present user or machine profile scripts.
However, at least the parameter -NoProfile seems not to work the same when Powershell.exe is being called fom the above CMD or PS1. Called from PS1, my machine profile gets nevertheless executed, but not fom CMD... interesting! The MSDN: PowerShell.exe Command-Line Help just says about this parameter: "Does not load the Windows PowerShell profile." Funny! There are six of them, see Technet: Understanding the Six PowerShell Profiles. I use "Current User, Current Host – console" and "All Users, Current Host – console". Lesson learned, but I am not sure if it's a bug or a feature.

MSBuild calling Powershell with credentials

I'm trying to deploy a windows service using an MSBuild script that runs a Powershell command.
The MSBuild script deploys the files I need and the PowerShell script will uninstall and reinstall the windows service using this command:
Invoke-Command -ComputerName IPAddressHere -FilePath "C:\theScriptFileName.ps1" -credential "TheUserName"
Using an IP address (which I need to because of different domains) I need to use credentials. The problem is that it prompts for a password, which won't work for TeamCity's automation.
I know I can save the credentials into a variable so that the prompt won't show, but I need to get it into a line something like the following that MSBuild can execute:
powershell.exe -NonInteractive -executionpolicy Unrestricted -command "& Invoke-Command -ComputerName IPAddressHere -FilePath 'C:\theScriptFileName.ps1' "
Is there a proper way to do this?
Use the code from Lee Holmes' article on exporting credentials:
function Export-Credential($cred, $path) {
$cred.Password = $cred.Password | ConvertFrom-SecureString
$cred | Export-Clixml $path
}
function Import-Credential($path) {
$cred = Import-Clixml $path
$cred.password = $cred.Password | ConvertTo-SecureString
New-Object System.Management.Automation.PSCredential($cred.username, $cred.password)
}
Save the credentials first in a regular session with the same user on the same machine that will be running the builds. (Well, on each such machine and user profile.) Then, in the build script, Import-Credential from the same path and pass the new $cred to Invoke-Command.
Maybe something like this?
$Creds = $host.ui.PromptForCredential("Need credentials", "Please enter username/password with proper rights on objects to manage.`r`n`r`nExample: AD-Domain\username", $env:userdomain + "\" + $env:username, "")
$IPAddressHere = "192.168.0.1"
powershell.exe -NonInteractive -executionpolicy Unrestricted -command "& {Invoke-Command -ComputerName $IPAddressHere -FilePath 'C:\theScriptFileName.ps1' -credentials $creds}"

Start-Process: Access is denied (even though i've provided credentials

I am getting the following error when trying to execute a line of code
Start-Process : This command cannot be executed due to the error:
Access is denied.
This is the code being executed
$username = "domain\username"
$passwordPlainText = "password"
$password = ConvertTo-SecureString "$passwordPlainText" -asplaintext -force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $username,$password
$powershellArguments = "D:\path\ps.script.ps1", "arg1", "arg2", "arg3", "arg4"
Start-Process "powershell.exe" -credential $cred -ArgumentList $powershellArguments -wait
This code works fine when executed locally, but not when called via vbs WMI
Both computers exist in the same domain and address range
The username and password supplied have admin privileges on both machines
I have tried both with and without -wait however neither works, and due to the user being privileged, I'd prefer to keep it
Q: Have you tried without the "-wait"?
Look at this link:
http://social.technet.microsoft.com/Forums/en-US/winserverpowershell/thread/3983a1e4-a663-47df-86f6-874d1828ea61/
The parameter "-wait" suppresses the command prompt or retains the
window until the process completes. This operation may require
administrator rights.