I try to create a service using PowerShell with following command in PowerShell script (.ps1):
c:\windows\system32\sc.exe create "blaService" displayname= "blaService" binpath= "\"C:\Program Files\xxxx\xxx xxx\xxxxx\xxxxxx.exe\"" start= "auto"
Then I go to the Registry Editor and I see in the ImagePath field (corresponding to the service I've created):
The result I'd expect to get is the same but quoted, so basically "C:\Program Files\xxxx\xxx xxx\xxxxx\xxxxxx.exe"
I followed this thread: When creating a service with sc.exe how to pass in context parameters?
All comments guide to do the same as I did, so I don't understand where am I wrong
A workaround using Start-Process:
#Requires -RunAsAdministrator
$sc_command = 'sc.exe create "blaService" displayname= "blaService" binpath= "\"d:\some path\to some.exe\"" start= "auto"'
$sc_command # make public command to process
$null = sc.exe delete blaService 2>$null # ensure that service does not exist
Start-Sleep -Seconds 2 # give some time to finish
Start-Process -FilePath "$env:comspec" -ArgumentList '/C', $sc_command
Start-Sleep -Seconds 3 # give some time to finish
# and ensure properly quoted ImagePath
reg.exe query HKLM\SYSTEM\CurrentControlSet\Services\blaService -v ImagePath
Output: D:\PShell\SO\73646083.ps1
sc.exe create "blaService" displayname= "blaService" binpath= "\"d:\some path\to some.exe\"" start= "auto"
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\blaService
ImagePath REG_EXPAND_SZ "d:\some path\to some.exe"
Finally, clear this absurd stuff from the registry:
sc.exe delete blaService
[SC] DeleteService SUCCESS
Related
I'm trying to create bat script that can start PowerShell script named the same as bat file in proper working directotry.
This is what I got:
#ECHO OFF
PowerShell.exe -NoProfile -Command "& {Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""%~dpn0.ps1""' -WorkingDirectory '%~dp0' -Verb RunAs}"
PAUSE
Passing working directory this way does not work.
How to make script that will pass proper working directroy and also command line arguments?
The -WorkingDirectory parameter doesn't work when using -Verb RunAs. Instead, you have to set the working directory by calling cd within a -Command string.
This is what I use: (cmd/batch-file command)
powershell -command " Start-Process PowerShell -Verb RunAs \""-Command `\""cd '%cd%'; & 'PathToPS1File';`\""\"" "
If you want to make a "Run script as admin" right-click command in Windows Explorer, create a new registry key at HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\Run with PowerShell (Admin)\Command, and set its value to the command above -- except replacing %cd% with %W, and PathToPS1File with %1 (if you want it to execute the right-clicked file).
Result: (Windows Explorer context-menu shell command)
powershell -command " Start-Process PowerShell -Verb RunAs \""-Command `\""cd '%W'; & '%1';`\""\"" "
EDIT: There's an alternative way to have the script be run as admin from Explorer, by using the "runas" sub-key: https://winaero.com/blog/run-as-administrator-context-menu-for-power-shell-ps1-files
If you want to run your script as admin from an existing powershell, remove the outer powershell call, replace %W with $pwd, replace %1 with the ps1 file-path, and replace each \"" with just ".
Note: The \""'s are just escaped quotes, for when calling from the Windows shell/command-line (it's quote-handling is terrible). In this particular case, just \" should also work, but I use the more robust \"" for easier extension.
See here for more info: https://stackoverflow.com/a/31413730/2441655
Result: (PowerShell command)
Start-Process PowerShell -Verb RunAs "-Command `"cd '$pwd'; & 'PathToPS1File';`""
Important note: The commands above are assuming that your computer has already been configured to allow script execution. If that's not the case, you may need to add -ExecutionPolicy Bypass to your powershell flags. (you may also want -NoProfile to avoid running profile scripts)
A workaround is to let the PowerShell script change the directory to it's own origin with:
Set-Location (Split-Path $MyInvocation.MyCommand.Path)
as the first command.
As per mklement0s hint: In PSv3+ use the simpler:
Set-Location -LiteralPath $PSScriptRoot
Or use this directory to open adjacent files.
$MyDir = Split-Path $MyInvocation.MyCommand.Path
$Content = Get-Content (Join-Path $MyDir OtherFile.txt)
I am using packer 0.12.1 to build an AWS ami based on the existing windows server 2016 ami.
The way I used to get it to work with windows server 2012 is to specify in the packer template:
"communicator": "winrm",
"winrm_username": "Administrator",
"winrm_use_ssl": true,
"winrm_insecure": true,
"user_data_file":"./ec2-userdata-winserver2016.ps1",
And the user data file would look like:
<powershell>
write-output "Running User Data Script"
write-host "(host) Running User Data Script"
Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force -ErrorAction Ignore
# Don't set this before Set-ExecutionPolicy as it throws an error
$ErrorActionPreference = "stop"
# Remove HTTP listener
Remove-Item -Path WSMan:\Localhost\listener\listener* -Recurse
$Cert = New-SelfSignedCertificate -CertstoreLocation Cert:\LocalMachine\My -DnsName "packer"
New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert.Thumbprint -Force
# WinRM
write-output "Setting up WinRM"
write-host "(host) setting up WinRM"
cmd.exe /c winrm quickconfig -q
cmd.exe /c winrm set "winrm/config" '#{MaxTimeoutms="1800000"}'
cmd.exe /c winrm set "winrm/config/winrs" '#{MaxMemoryPerShellMB="1024"}'
cmd.exe /c winrm set "winrm/config/service" '#{AllowUnencrypted="true"}'
cmd.exe /c winrm set "winrm/config/client" '#{AllowUnencrypted="true"}'
cmd.exe /c winrm set "winrm/config/service/auth" '#{Basic="true"}'
cmd.exe /c winrm set "winrm/config/client/auth" '#{Basic="true"}'
cmd.exe /c winrm set "winrm/config/service/auth" '#{CredSSP="true"}'
cmd.exe /c winrm set "winrm/config/listener?Address=*+Transport=HTTPS" "#{Port=`"5986`";Hostname=`"packer`";CertificateThumbprint=`"$($Cert.Thumbprint)`"}"
cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes
cmd.exe /c netsh firewall add portopening TCP 5986 "Port 5986"
cmd.exe /c net stop winrm
cmd.exe /c sc config winrm start= auto
cmd.exe /c net start winrm
</powershell>
This works fine in windows server 2012, but not anymore in windows server 2016.
For server 2016, the output of packer is:
==> eu-west-1-builder: Waiting for auto-generated password for instance...
eu-west-1-builder: It is normal for this process to take up to 15 minutes,
eu-west-1-builder: but it usually takes around 5. Please wait.
eu-west-1-builder:
eu-west-1-builder: Password retrieved!
==> eu-west-1-builder: Waiting for WinRM to become available...
And it hangs until timeout.
As AWS release windows server 2016 ami fairly recently, I couldn't find much information. I am not really a windows guru (I am usually on linux)
Any help / suggestions would be greatly appreciated.
Try changing "winrm_username" to something other than Administrator
As per Packer documentationThe default user name is packer not root as in other builders. Most distros on Azure do not allow root to SSH to a VM hence the need for a non-root default user. Set the ssh_username option to override the default value.
I want to run multiple commands in one batch file.
I tried the &, &&, start, /wait, call, :begin and goto begin commands but no luck.
Here are my commands:
C:\Windows\System32\cmd.exe /k %windir%\System32\reg.exe ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /t REG_DWORD /d 0 /f
sc config remoteregistry start= auto
sc start remoteregistry
sc config Schedule start=auto
sc start Schedule
sc stop McAfeeFramework
sc configure McAfeeFramework startup= disabled
sc stop McShield
sc configure McShield startup= disabled
sc stop McTaskManager
sc configure McTaskManager startup= disabled
netsh advfirewall set AllProfiles state off
sc stop MpsSvc
sc config MpsSvc start= disabled
C:\Windows\System32\cmd.exe /k <command>
starts a new cmd context where is executed, but /k keeps that new context open. You want to close it after executing , so further commands from the original context can be executed. Use /c instead of /k to do so.
described in cmd /?
Well, batch scripts already do it by default, but i guess that your usage of /K on cmd.exe it was unnecessary and harmful, and A / C could have done the job even though, remembering, it is not necessary.
File1.bat*
C:\Windows\System32\cmd.exe /c %windir%\System32\reg.exe ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /t REG_DWORD /d 0 /f
sc config remoteregistry start= auto
sc start remoteregistry
sc config Schedule start=auto
sc start Schedule
sc stop McAfeeFramework
sc configure McAfeeFramework startup= disabled
sc stop McShield
sc configure McShield startup= disabled
sc stop McTaskManager
sc configure McTaskManager startup= disabled
netsh advfirewall set AllProfiles state off
sc stop MpsSvc
sc config MpsSvc start= disabled
So I've got this pretty basic powershell script to backup files to our network drive:
Function Backup {
param ($backupSource)
#Define backup location
$backupTarget = '\\192.168.0.247\Public'
#Make sure we're targeting a folder
If (!(Test-Path $backupSource -pathtype container)) {
[System.Windows.Forms.MessageBox]::Show("Target must be a folder" , "Error", 0)
Exit
}
#Make sure we have access to the backup location
DO {
$test = Test-Path $backupTarget
If (!$test) {
$loop = [System.Windows.Forms.MessageBox]::Show("Is the WiFi on? I can't reach the public drive. Maybe try again in a second." , "Internet Connection Unavailable" , 5)
If ($loop -eq 'Cancel') {
Exit
}
}
} WHILE (!$test)
Copy-Item $backupSource $backupTarget -recurse
}
I'm trying to get it to work in a right click menu, making it show up is no problem, and it executes, but I can't figure out how to successfully feed it the $backupSource parameter.
I'm working out of HKEY_CLASSES_ROOT\Directory\shell\NASBackup\command with my default key. I've tried every combination of "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -File "C:\Windows\System32\Backup.ps1" "%1" I can think of. Can someone please help me out with the syntax here?
The script as provided doesn't work with command line arguments. i.e. calling the script as is doesn't work.
Try adding the call to the function passing the command line arguments.
At the end of your script add:
Backup $args[0]
I do it like this.
First I start cmd.exe from inside the registry. CMD window will appear briefly while it sends the powershell command.
Second I call powershell with the hidden switch so the rest of it runs invisibly.
Below is a working .reg file.
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Directory\shell\NASBackup\command]
#="cmd /c start /b /wait powershell.exe -nologo -WindowStyle Hidden -file C:\\Windows\\System32\\Backup.ps1"
;
Here is a powershell snip to set the same bits in the registry.
If ( -Not ( Test-Path "Registry::HKEY_CLASSES_ROOT\Directory\shell\NASBackup\command")){New-Item -Path "Registry::HKEY_CLASSES_ROOT\Directory\shell\NASBackup\command" -ItemType RegistryKey -Force}
Set-ItemProperty -path "Registry::HKEY_CLASSES_ROOT\Directory\shell\NASBackup\command" -Name "(Default)" -Type "String" -Value "cmd /c start /b /wait powershell.exe -nologo -WindowStyle Hidden -file C:\Windows\System32\Backup.ps1"
#
Maybe there is a way to do it with Start-Process cmdlet that I cannot find? The other related Q/A's I found on StackOverflow such as this, this and this all give a solution to do this with a custom C# code. My question is specifically, is there any straightforward way to do this in PowerShell? i.e. you are in an elevated PS console and want to run a process as non-admin.
You can specify the TrustLevel with runas.exe, effectively running "restricted"
runas /trustlevel:0x20000 "powershell.exe -command 'whoami /groups |clip'"
You should see in the output from whoami that the Administrators group in your token is marked as "Used for Deny only"
When you dig into this problem, as mentioned by the linked tasks, there is no way to run a UAC "non" elevated process from a elevated process. Since this is exactly what I required and the runas solution didn't work for me I converted the code workaround supplied by Microsoft to use a scheduled task to Start a "non" elevated process.
Example of running powershell.exe as a "non" elevated process from a elevated powershell prompt:
$apppath = "powershell.exe"
$taskname = "Launch $apppath"
$action = New-ScheduledTaskAction -Execute $apppath
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date)
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName $taskname | Out-Null
Start-ScheduledTask -TaskName $taskname
Start-Sleep -s 1
Unregister-ScheduledTask -TaskName $taskname -Confirm:$false
The above powershell commands only work on Windows Server 2012 / Windows 8 and greater only.
Or you can use the SCHTASKS.EXE application instead to cover most versions of windows:
$apppath = "powershell.exe"
$taskname = "Launch $apppath"
schtasks /create /SC ONCE /ST 23:59 /TN $taskname /TR $apppath
schtasks /run /tn $taskname
Start-Sleep -s 1
schtasks /delete /tn $taskname /F
Another, limited, way: Make Windows Explorer launch it for you
PS C:\> explorer.exe "C:\windows\system32\cmd.exe"
Just use the full path and extension. But it does NOT accept parameters.
I tried creating a batch file. But explorer refuses to launch .BAT or .CMD.
You can run a non-admin process from an elevated session by passing in the credential of the user you want to run as. You can use Get-Credential if you want to run interactively, or you can use Import-Clixml or SecretStore or some other established mechanism for storing and retrieving credentials if you want a script to run unattended. E.g.:
$credential = Get-Credential -UserName $Env:USERNAME
# or
$credential = Import-Clixml -Path 'C:\MyCredential.cred'
Start-Process -FilePath pwsh.exe -ArgumentList '-noprofile' -Credential $credential -Wait
in start-process exist switch runas like
start-process powershell -verb runAs
but still uac check you if in your system uac on you should first bypass uac there are many way exist for bypass uac but all ways doesn't work in all windows like windows 8
if you write script for run process then compile to exe you can use program like runasadmin for run as admin your exe in system but still not work in windows 8