How can I successfully run my script with administrator permissions? - powershell

I've been working on a small, redeployable .ps1 script that will be used to automate the clearing of the end user's print spooler and clearing of the printing queue, with more features in future implementation. Here's a snippet of some of the commands that require elevation.
net stop spooler
Remove-Item C:\Windows\System32\spool\PRINTERS\* -Force
net start spooler
In order to successfully run this script on end user's computers, I've created a Powershell credential object like so. (It doesn't matter if the administrator credentials are in clear text, since it is executed in the background over RMM).
$password = "adminpassword" | ConvertTo-SecureString -asPlainText -Force
$username = "adminusername"
$credential = New-Object System.Management.Automation.PSCredential($username,$password)
However, when I try to run any command with the newly made variable like this,
net stop spooler -credential $credential
I get some sort of complication, such as the PS window only returning the syntax of the command instead of actually running it. I'm relatively inexperienced in the Powershell automation; If someone could offer up a solution as to how to best integrate the newly made credential object into my script so that it will run with elevated permissions in its entirety, It'd be much appreciated.

net stop is not a PowerShell command and won't take a credential object.
Here is an example of how to do this if you are running locally elevated:
stop-service -Name spooler

Related

Looking to map an Azure Fileshare as a mapped network drive on an Azure Windows VM via another machine/Custom Script Execution

I'm attempting to provision a Windows VM and I need to map some Azure fileshares to drives for the VM user that will be interacting with the VM.
I've been trying to make "az vm extension set"/Custom Script Execution work for me by calling some PowerShell scripts to setup the mapping to the fileshare, but since the process runs as NT AUTHORITY\SYSTEM, the mappings aren't working, obviously. I've tried to switch user contexts in my scripts via having an intermediate script that changes context to my VM user and then calling another script that does the work, but that doesn't seem to be working.
$scriptFile = $args[0]
$username = $args[1]
$password = $args[2]
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $username,
$securePassword
Start-Process Powershell.exe -Credential $credential $scriptFile
Unfortunately it seems nothing gets run in the $scriptFile that I call, and I can't get any errors out of standard out/err, so I'm at a loss as to how this can be done.
Certainly someone out there has had to run scripts as another user via the Custom Script Execution method before, I'm hoping they happen to read this post.
Is there a way to set what user the Custom Script Execution runs as?
No, there is no way of setting a user under which script extension runs.
You also should use -PassThru and -Wait and\or -RedirectStandardError\-RedirectStandardInput to your command invocation. Also, add -ErrorAction Stop to your commands to propagate errors.

Start-job results in "The background process reported an error with the following message: ."

I have a simple Powershell script (that's being run in a step in Octopus deploy) that I'm trying to run as another user. We need it for future steps (each application on our platform runs as its own user account, and I need to be able to run an arbitrary script as that user during the deployment process).
The problem is that even the simplest script fails with completely unhelpful error messages, such as this:
$secpasswd = ConvertTo-SecureString $OctopusParameters["runAsPassword"] -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ($OctopusParameters["runAsUsername"] , $secpasswd)
$job = Start-Job -scriptblock {
whoami
} -credential $credential
$job | Receive-Job -Wait
Which fails with the message:
The background process reported an error with the following message: .
The Octopus tentacle is running as a domain account with admin privileges on the machine.
I've completely exhausted all avenues of investigation now, but we really need to get this working. I think if we can't run a deployment script as a certain user then we're completely screwed.
Nearly three years later I have the same issue... I tried writing the code to a temporary file and using Start-Process, but couldn't get that to work either.
In the end, I wrote the code to file, and then ran it through the Windows task scheduler.

Running a uninstaller as administrator remotely over Powershell

I am working on a small software deployment script which uninstalls and installs a new version of Check_MK remotely by using powershell.
Everything is working great - i am able to localize the old service, stop it and determine the installation path of it. The problem is to run the "uninstall.exe" of the service.
This can be easily done by using a Powershell session logging on the server with credential parameter in use.
$passwd = convertto-securestring -AsPlainText -Force -String "password"
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "domain\user",$passwd
$session = new-pssession -computername "192.xxx.xxx.xxx" -credential $cred
Enter-PSSession $session
The problem is you can't use PSSession in a script - it is made for personal use and not automation.
So i tried to use Powershells Invoke-Command cmdlet.
Invoke-Command -Computername "192.xxx.xxx.xxx" -credential $cred -argumentlist $cred -ScriptBlock {
# Lots of stuff and enter uninstall directory
uninstall.exe /S
}
Calling the exe file ends in a query for administrator credentials.
I also tried to remote start a elevated Powershell session and use it for uninstallation..
Start-Process powershell -Credential $cred
Executing a script located on the server for starting uninstall.exe using the elevated Powershell session ends in a UAC query (not querying for credentials, but asking for executing).
Is there any other solution to handle this? I tried a lot more, but nothing worked.
Here's another approach, using Schedule Tasks.
Create a task locally using the logged-on user credentials, you must have admin rights on the remote computer of course.
Function Run-RemoteCommand
{
Param(
[Parameter(Mandatory = $true)]
[String]
$Computer,
[Parameter(Mandatory = $true)]
[String]
$Task,
[Switch]
$Background
)
$TaskName = "TempTask"
$Explorer=gwmi win32_process -ComputerName $Computer | ? {$_.ProcessName -eq "explorer.exe" }
$OWner = $Explorer.GetOwner().Domain + "\" + $Explorer.GetOwner().User
if ($Background)
{
$Create = "SCHTASKS /Create /TN ""$TaskName"" /RU System /TR ""$Task"" /SC Once /ST 22:30"
}
Else
{
$Create = "SCHTASKS /Create /TN ""$TaskName"" /RU $Owner /TR ""$Task"" /SC Once /ST 22:30"
}
$Runit = "SCHTASKS /Run /TN ""$TaskName"""
$Delete = "SCHTASKS /Delete /TN ""$TaskName"" /F"
$WMI = Get-WmiObject -List Win32_Process -ComputerName $Computer
$WMI.Create($Create)
$WMI.Create($Runit)
Sleep 2
$WMI.Create($Delete)
}
To Run it:
Run-RemoteCommand -Computer "192.xxx.xxx.xxx" -Task 'c:\path\uninstall.exe /S'
if you want to run it as 'NT AUTHORITY\SYSTEM' add the -Background Switch
The best way would be to always have the local shell run as an elevated user. This allows you to start invoke-command without providing credentials in a script.
Once you have a Powershell running as an administrative user, and you can run your script using invoke-command. I do it all the time.
If you are scheduling this task, you will have to have the task run as the elevated user. This again, stops you from having to put the password in plain text in the script.
You don't mention if this is in a domain context or not.
If it is in a domain context, you could use a startup script in a Group Policy Object to accomplish your goal. It will execute on the next reboot of the workstation.
You can also do it without a group policy, but it means visiting each computer individually and changing the local group policy object - at that point, you might as well just run the powershell script.
Another solution: you could create a .zap file and deploy that using Group Policy's software deployment functionality. This would be a bit of an abuse of the system. .zap files are meant to install software that isn't packaged in MSI files, but you could also use it to launch a script that uninstalls your software. Ordinarily, .zap files cannot be uninstalled.
A third option: download Chocolatey from http://www.chocolatey.org. This is a PowerShell script that can manage the installation of a lot of standard software for you. Configure it on each workstation to run automatically (using the scheduler or so). Create a NuGet package for your software (NuGet is what Chocolatey runs under the hood), and use chocolatey to deploy or undeploy your software as needed.
As an aside, instead of rolling your own installer, you may want to consider converting it to an MSI file - those can easily be installed and uninstalled, even remotely, without excessive UAC hassle. You could also use a NullSoft installer, but those are harder to automate remotely. MSI is Microsoft's official installation method.
Some people create MSI wrappers around standard .exe-type installers, too.

teamcity powershell - unable to run batch file

I've spent quite a bit of time banging my head on this one. A little StackOverflow help please, good folks!
Scenario: We are trying to run a custom .bat file located on the CI server via the TeamCity Powershell step.
When powershell script is run on local box manually, it kicks off .bat file correctly.
When powershell script is run through TeamCity, it successfully 'sees' the .bat file (validated by receiving a 'cannot find file' response when I rename the .bat file it is expecting)
HOWEVER, we have not seen any indication that the .bat file was actually kicked off.
What we've tried:
We've added the 'RedirectStandardOutput' and 'RedirectStandardError' for attempt to diagnose, but although the log file is created, it is returned blank.
We've granted filepath permissions and tried two different credentials including the credential of the TC build agent
Added "-wait" at one point to see if we needed to 'tell' PS to wait on the .bat file.
Two questions...
What is preventing us from running this .bat file?
How do we diagnose issues like this? ATM it is a 'blackbox' to us.
TeamCity Powershell settings:
Powershell Run Mode: Version 1.0; Bitness x64 (tried x86 as well)
Working Directory: Tried as blank, and specific filepath of .bat file (so, 'D:\folder\folder2\')
Script: Source Code
Script Execution: Execute .ps1 from external file (tried with 'Put script into PowerShell stdin with "-Command -" argument' as well)
Add -NoProfile argument (tried both)
Powershell script:
#Predefine necessary information
$Username = "DOMAIN\username"
$Password = "password"
$ComputerName = "CI Build Server Name"
#Create credential object
$SecurePassWord = ConvertTo-SecureString -AsPlainText $Password -Force
$Cred = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $Username, $SecurePassWord
#Start batch file
Start-Process "testbat.bat" -WorkingDirectory D:\file\path\ -Credential ($Cred)-NoNewWindow -RedirectStandardError stderr.txt -RedirectStandardOutput stdout.txt
Write-Host "Executed powershell."
UPDATE 1: If we remove the '-Credential ($Cred)' portion we are able to kick off the testbat.bat file from TeamCity, as expected. The problem must lie with that "-Credential ($Cred)" argument, somehow. Any thoughts?
UPDATE 2: If we set the '-Credential ($Cred)' portion to the credential of the build agent user we are able to kick off the test.bat file from TeamCity. The problem only occurs when we set the credential to a user other than the one running the build agent. This seems to indicate that credential syntax is fine.
UPDATE 3: Tried running with PowerShell executionpolicy set to 'RemoteSigned' and 'Unrestricted'. Problem persists.
UPDATE 4: Gave the BuildAgent user, and the user of whom we want to run this as, full permissions to powershell via 'Set-PSSessionConfiguration'. Problem persists.
$credential = New-Object System.Management.Automation.PsCredential(".\user", (ConvertTo-SecureString "pass" -AsPlainText -Force))
Start-Process powershell -Credential $credential -ArgumentList '-noprofile -command &{Start-Process D:\file\path\test.bat -NoNewWindow -RedirectStandardError stderr.txt -RedirectStandardOutput stdout.txt }'
note:
first i get credential "user" ur user then convert your pass to plain text
then start-process with your credential set
If agent is running as service under Local System account, then it's not possible to run PowerShell under specified account. The workarounds are:
Run agent via command line.
Try to run agent service under another account (not Local System) with administrator rights, probably it will help.
Try RunAs plugin. It provides an ability to run builds under the specified user account.

How do I execute a powershell script under a specified credential without a prompt?

I'm writing an 'Action Script' in VMWare AppDirector 'AppD' which installs MS Dynamics. (My action script is actually a powershell script). The way this works is that AppD will execute a powershell script on a newly deployed server, using a builtin administrator account. This script is one of the last steps in a highly orchestrated deployment. At this stage my SQL server has been deployed, the databases loaded, and I'm performing the final deployment.
When I run my script logged in as myself, everything works great. But of course that's executing under 'mydomain\myusername' which has access to the SQL server etc. However, when AppD executes this script under a local builtin account, it doesn't have the credentials needed by setup to authenticate against SQL, and make proper connections for install to succeed.
My first attempt was to just call a script, that invokes my actual deployment script, so I can pass credentials;
$user = "mydomain\myusername"
$pword = ConvertTo-SecureString -String "mypassword" -AsPlainText -Force
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $pword
Invoke-Command -FilePath "C:\Scripts\DeployAOS.ps1" -Credential $credential -Computer localhost
This looked like it might have worked, but when reviewing the install log I see the following error;
2015-03-09 13:15:19Z Property DbSqlServer set to: 'SQLSERVER001'
2015-03-09 13:15:23Z Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'.
My original DeployAOS.ps1 script contains this line, which kicks off the install;
# Perform AOS Installation
Start-Process -FilePath $exeAOSSetup -ArgumentList $cfgAOS -Wait
I have also tried just modifying my DeployAOS.ps1 to set the 'System.Management.Automation.PSCredential' object w\ Username\Password, and doing something like this;
# Perform AOS Installation
Start-Process -FilePath $exeAOSSetup -ArgumentList $cfgAOS -Credential $credentials -Wait
And it really didn't like that. It feels like the AOS setup needs to be executed under a domain user, that has access to the SQL server, and maybe even have a user profile loaded while setup runs (So it can create a desktop shortcut, etc.)
Any ideas how I might go about solving this problem? I'm fairly new to scripting in powershell, so any help would be appreciated.