I want to automate the encryption files placed in a folder using GPG on Windows Server 2019. I tried calling gpg.exe from the script but it doesn't create any output files. I also tried using debug & verbose to check values that are being set. There is no exception after gpg.exe is called, but no output files are generated.
[CmdletBinding()]
param()
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser
$key = "test#test.com"
$GpgPath = "C:\Program Files (x86)\GnuPG\bin\gpg.exe"
$localuser = "local#local.com"
$outputdir = "D:\ToBeEncrypted\Output\"
$archivedir = "D:\ToBeEncrypted\Archive\"
$passPhrase = "password"
$sourcePath = "D:\ToBeEncrypted\*.dat"
$filearray = Get-ChildItem -Path $sourcePath
foreach ($file in $filearray) {
$fileName = $file.Name
$encryptedFileName = "$outputdir" + $fileName + ".txt"
Write-Verbose "Encrypted name: $encryptFileName"
try
{
Write-Verbose "GPG Execution Started $file to $encryptedFileName"
Start-Process -FilePath $GpgPath -ArgumentList "--pinentry-mode=loopback --passphrase $passPhrase --compress-algo 1 --cipher-algo cast5 --armor --recipient $key --local-user $localuser --output $encryptedFileName -se $file"
}
catch [Exception]
{
Write-Verbose $_.Exception.Message
exit 1
}
Write-Verbose "GPG Execution Completed"
}
What am I doing wrong in this script?
Related
I made a small Powershell script 'Start.ps1' which launches some websites on Windows startup. When I launch it manually, all configured websites are started in Chrome. However, when I run it with task scheduler, the task runs, but Chrome does not start.
schtasks /create /tn "Start" /sc onstart /delay 0000:30 /rl highest /ru system /tr "powershell.exe -file 'C:\Users\myuser\Google Drive\Home\Start.ps1'"
I've also added some logs in my powershell script so I'm sure the script has started:
Function Write-Log {
Param (
[parameter(Mandatory=$True,HelpMessage='Log output')][string]$Log,
[parameter(Mandatory=$True,HelpMessage='Log severity')][ValidateSet('Debug', 'Info', 'Warning', 'Error', 'Unknown')][string]$Severity,
[parameter(Mandatory=$True,HelpMessage='Log message')][string]$Message
)
$Now = Get-Date -Format 'yyyy-MM-dd HH:mm:ss,fff'
$LocalScriptName = Split-Path -Path $myInvocation.ScriptName -Leaf
If ( $Log -eq 'Verbose' ) {
Write-Verbose -Message ('{0}: {1}: {2}: {3}' -f $Now, $LocalScriptName, $Severity, $Message)
}
ElseIf ( $Log -eq 'Debug' ) {
Write-Debug -Message ('{0}: {1}: {2}: {3}' -f $Now, $LocalScriptName, $Severity, $Message)
}
ElseIf ( $Log -eq 'Output' ) {
Write-Verbose -Message ('{0}: {1}: {2}: {3}' -f $Now, $LocalScriptName, $Severity, $Message)
}
ElseIf ( $Log -match '^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])(?::(?<port>\d+))$' -or $Log -match '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' ) {
$IpOrHost = $log.Split(':')[0]
$Port = $log.Split(':')[1]
If ( $IpOrHost -match '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' ) {
$Ip = $IpOrHost
}
Else {
$Ip = [Net.Dns]::GetHostAddresses($IpOrHost)[0].IPAddressToString
}
Try {
$LocalHostname = ([Net.Dns]::GetHostByName((& "$env:windir\system32\hostname.exe")).HostName).tolower()
$JsonObject = (New-Object -TypeName PSObject |
Add-Member -PassThru -NotePropertyName NoteProperty -NotePropertyValue logsource -InputObject $LocalHostname |
Add-Member -PassThru -NotePropertyName NoteProperty -NotePropertyValue hostname -InputObject $LocalHostname |
Add-Member -PassThru -NotePropertyName NoteProperty -NotePropertyValue scriptname -InputObject $LocalScriptName |
Add-Member -PassThru -NotePropertyName NoteProperty -NotePropertyValue logtime -InputObject $Now |
Add-Member -PassThru -NotePropertyName NoteProperty -NotePropertyValue severity_label -InputObject $Severity |
Add-Member -PassThru -NotePropertyName NoteProperty -NotePropertyValue message -InputObject $Message )
If ( $psversiontable.psversion.major -ge 3 ) {
$JsonString = $JsonObject | ConvertTo-Json
$JsonString = $JsonString -replace "`n",' ' -replace "`r",' '
}
Else {
$JsonString = $JsonObject | ConvertTo-Json2
}
$Socket = New-Object -TypeName System.Net.Sockets.TCPClient -ArgumentList ($Ip,$Port)
$Stream = $Socket.GetStream()
$Writer = New-Object -TypeName System.IO.StreamWriter -ArgumentList ($Stream)
$Writer.WriteLine($JsonString)
$Writer.Flush()
$Stream.Close()
$Socket.Close()
}
Catch {
Write-Verbose -Message ("{0}: {1}: Error: Something went wrong while trying to send message to logserver `"{2}`"." -f $Now, $LocalScriptName, $Log)
}
Write-Verbose -Message ('{0}: {1}: {2}: Ip: {3} Port: {4} JsonString: {5}' -f $Now, $LocalScriptName, $Severity, $Ip, $Port, $JsonString)
}
ElseIf ($Log -match '^((([a-zA-Z]:)|(\\{2}\w+)|(\\{2}(?:(?:25[0-5]|2[0-4]\d|[01]\d\d|\d?\d)(?(?=\.?\d)\.)){4}))(\\(\w[\w ]*))*)') {
If (Test-Path -Path $Log -pathType container){
Write-Host ('{0}: {1}: Error: Passed Path is a directory. Please provide a file.' -f $Now, $LocalScriptName)
Exit 1
}
ElseIf (!(Test-Path -Path $Log)) {
Try {
$Null = New-Item -Path $Log -ItemType file -Force
}
Catch {
$Now = Get-Date -Format 'yyyy-MM-dd HH:mm:ss,fff'
Write-Host ("{0}: {1}: Error: Write-Log was unable to find or create the path `"{2}`". Please debug.." -f $Now, $LocalScriptName, $Log)
exit 1
}
}
Try {
('{0}: {1}: {2}: {3}' -f $Now, $LocalScriptName, $Severity, $Message) | Out-File -filepath $Log -Append
}
Catch {
Write-Host ("{0}: {1}: Error: Something went wrong while writing to file `"{2}`". It might be locked." -f $Now, $LocalScriptName, $Log)
}
}
}
$Logfile="c:\Tempo\Start.log"
Write-Log $Logfile Info "Initiating Chrome Site Startup"
Start-Process -FilePath "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
Start-Process -FilePath "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" -ArgumentList "https://outsideit.net"
Start-Process -FilePath "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" -ArgumentList "https://psychologischezorgopmaat.be"
Start-Process -FilePath "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" -ArgumentList "https://github.com"
Start-Process -FilePath "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" -ArgumentList "https://gitlab.com"
Start-Process -FilePath "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" -ArgumentList "http://localhost:9200"
Start-Process -FilePath "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" -ArgumentList "http://localhost:5601"
Write-Log $Logfile Info "Finalizing Chrome Site Startup"
How can I make this work in Task Scheduler? I tried running it with SYSTEM and my own user and with the "Run with highest privilege" option.
Always test if the scheduled task is working as intended when you run it manually (Scheduled Tasks - right click your task and Run it). When that works, move on to test if it works as intended when you start up the computer (or whenever, depending on the trigger).
When I imported your task with through cmd with the SYSTEM user account, the default setting was "Run whether user is logged on or not". If I tried to run it manually, the script wouldn't start.
I then changed the user to my account, changed the option to "Run only when the user is logged on", and that fixed the problem for me (many times before, as well). I wasn't able to change this option when using the SYSTEM user.
I am building a deployment script to install software on a new device using a ppkg file.
The script looks at which drive is the USB drive and copies the software over to the local temp folder and runs them according to a set of variables as shown below.
What I am struggling to do is simplify the script so I am not repeating code 7 times down the page, I want to just run a loop 7 times to pull in the needed software. I tried an array but I think I am not quite understanding it completely.
This is my script so far with the repeating code:
#SOE application Variables
#applcation1 CM_client
$app1name = "Config Manager Client 1706"
$app1skip = "no"
$app1path = "$env:SystemDrive\temp\soe\application_installs\app1\CM_client_inst_1706\"
$app1runcommand = "clientx64.bat"
$app1arguments = ""
#applcation2
$app2name = "Office 2016 Pro Plus"
$app2skip = "no"
$app2path = "$env:SystemDrive\temp\soe\application_installs\app2\O2016\"
$app2runcommand = "setup.exe"
$app2arguments = "/configure configuration.xml"
#log Folder
$datetime = Get-Date -format "yyyy.MM.dd-HH.mm.ss"
$logpath = "$env:ALLUSERSPROFILE\SOEInst_ppkg\$datetime"
New-Item -Path $logpath -ItemType Directory -ErrorAction SilentlyContinue
#Transcript Start
Start-Transcript -Path $logpath\SOE-app-installer-ppkg-$datetime.log
#Timer Function
$pkgremovetime = Get-Date -format "HH:mm:ss"
write-host "Script Start Time - $pkgremovetime"
#Find USB Drive
Write-host Discovering USB Drive
$drives = (GET-WMIOBJECT –query “SELECT * from win32_logicaldisk").DeviceID
foreach ($drive in $drives) {
$usbdrive = (dir $drive USBIMG.FILE | Select-Object -Unique "USBIMG.FILE")
if ($usbdrive -match "USBIMG.FILE*") {
$datadrive = $drive
}
}
Write-host Found $datadrive is the USB drive
#Copy Applications to Local Drive
Write-Host Creating Installer Folder
New-Item -Path $env:SystemDrive\temp\SOE -ItemType Directory
Copy-Item $datadrive\application_installs $env:SystemDrive\temp\soe -Recurse -Verbose
#Install Applications
#Application 1
if ($app1skip -eq "no") {
if ($app1arguments) { #Arguments Variable Populated
Write-Host Installing Applcation 1 `($app1name`)
$app1 = Start-Process -Wait -FilePath $app1path$app1runcommand -ErrorAction Continue -ArgumentList $app1arguments -WindowStyle Normal
if ($app1.ExitCode -eq "0") {
Write-Host $app1name Installed ok
} Else {
Write-host $app1name install exited with code $app1.ExitCode
}
}
}Else { #Argurments Variable Empty
Write-Host Installing Applcation 1 `($app1name`)
$app1 = Start-Process -Wait -FilePath $app1path$app1runcommand -ErrorAction Continue -WindowStyle Normal
if ($app1.ExitCode -eq "0") {
Write-Host $app1name Installed ok
} Else {
Write-host $app1name install exited with code $app1.ExitCode
}
}
#Application 2
if ($app2skip -eq "no") {
if ($app2arguments) { #Arguments Variable Populated
Write-Host Installing Applcation 2 `($app2name`)
$app2 = Start-Process -Wait -FilePath $app2path$app2runcommand -ErrorAction Continue -ArgumentList $app2arguments -WindowStyle Normal
if ($app2.ExitCode -eq "0") {
Write-Host $app2name Installed ok
} Else {
Write-host $app2name install exited with code $app2.ExitCode
}
}
}Else { #Argurments Variable Empty
Write-Host Installing Applcation 2 `($app2name`)
$app2 = Start-Process -Wait -FilePath $app2path$app2runcommand -ErrorAction Continue -WindowStyle Normal
if ($app2.ExitCode -eq "0") {
Write-Host $app2name Installed ok
} Else {
Write-host $app2name install exited with code $app2.ExitCode
}
}
#cleanup
Remove-Item $env:SystemDrive\temp\soe -Recurse -Force -Verbose
#get end time
$pkgremovetime_end = Get-Date -format "HH:mm:ss"
#calculate time difference
$timetaken = New-TimeSpan $pkgremovetime $pkgremovetime_end
if ($timetaken.Seconds -lt 0) {
$Hrs = ($timetaken.Hours) + 23
$Mins = ($timetaken.Minutes) + 59
$Secs = ($timetaken.Seconds) + 59 }
else {
$Hrs = $timetaken.Hours
$Mins = $timetaken.Minutes
$Secs = $timetaken.Seconds }
$Difference = '{0:00}:{1:00}:{2:00}' -f $Hrs,$Mins,$Secs
#log time difference
write-host "Script End Time - $pkgremovetime_end"
Write-Host "Total time taken $difference"
#Transcript End
Stop-Transcript
I suggest you make a function which takes in the variables. I did a quick comparison of your installation codes and something like this should work
function installApplication{
Param($skip, $arguments, $name, $path, $runcommand)
if ($skip -eq "no"){
if ($arguments){
write-host "Installing Application $appname"
$app = Start-Process -Wait -FilePath $path$runcommand -ErrorAction....
if($app.ExitCode -eq "0"){
....
....
}
and so on, You can then call the function using
installApplication $app1skip $app1arguments $app1name $app1path $app1runcommand
installApplication $app2skip $app2arguments $app2name $app2path $app1runcommand
Your input arguments will replace the function parameters in the order you pass them in, or you can use -skip $app1skip to assign the parameters.
If your repeating the same code too many times, I suggest throwing it into something like diffchecker, put the code into a function and replace all the differences with variables.
You can see your code here https://www.diffchecker.com/FxAIdD6g (1 Day only)
Update2:
Now, when I know, that x32 is the problem I debugged into the script using powershell_ise_x32 and found out, that $Word.Documents is null.
So Powershell-API for Word has a different behaviour in x32 PowerShell, then in 64bit.
Update:
The error occurs, when using PowerShell x32 and occurs NOT on PowerShell 64bit. That was really it. Powershell x32 was executed because I started it from the Total Commander 32bit.
The question is now - why 32bit and 64bit PowerShell have different behaviour?
Initial Question:
I wrote a powershell script, to convert my WordDocuments and merge them to one.
I wrote a Batch script, to start this powershell script.
When I execute the script directly in "Powershell ISE" the script works fine.
When I execute the batch script as Administrator via context menu, the script reports errors. In this case the C:\WINDOWS\SysWOW64\cmd.exe is executed.
When I execute another cmd.exe found on my system as Administrator - everything works fine:
"C:\Windows\WinSxS\amd64_microsoft-windows-commandprompt_31bf3856ad364e35_10.0.15063.0_none_9c209ff6532b42d7\cmd.exe"
Why do I have different behaviour in different cmd.exe? What are those different cmd.exe?
Batch Script:
cd /d "%~dp0"
powershell.exe -noprofile -executionpolicy bypass -file "%~dp0%DocxToPdf.ps1"
pause
Powershell Script
$FilePath = $PSScriptRoot
$Pdfsam = "D:\Programme\PDFsam\bin\run-console.bat"
$Files = Get-ChildItem "$FilePath\*.docx"
$Word = New-Object -ComObject Word.Application
if(-not $?){
throw "Failed to open Word"
}
# Convert all docx files to pdf
Foreach ($File in $Files) {
Write-Host "Word Object: " $Word
Write-Host "File Object: " $Word $File
Write-Host "FullName prop:" $File.FullName
# open a Word document, filename from the directory
$Doc = $Word.Documents.Open($File.FullName)
# Swap out DOCX with PDF in the Filename
$Name=($Doc.FullName).Replace("docx","pdf")
# Save this File as a PDF in Word 2010/2013
$Doc.SaveAs([ref] $Name, [ref] 17)
$Doc.Close()
}
# check errors
if(-not $?){
Write-Host("Stop because an error occurred")
pause
exit 0
}
# wait until the conversion is done
Start-Sleep -s 15
# Now concat all pdfs to one single pdf
$Files = Get-ChildItem "$FilePath\*.pdf" | Sort-Object
Write-Host $Files.Count
if ($Files.Count -gt 0) {
$command = ""
Foreach ($File in $Files) {
$command += " -f "
$command += "`"" + $File.FullName + "`""
}
$command += " -o `"$FilePath\Letter of application.pdf`" -overwrite concat"
$command = $Pdfsam + $command
echo $command
$path = Split-Path -Path $Pdfsam -Parent
cd $path
cmd /c $command
}else{
Write-Host "No PDFs found for concatenation"
}
Write-Host -NoNewLine "Press any key to continue...";
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown");
I've found $PSScriptRoot to be unreliable.
$FilePath = $PSScriptRoot;
$CurLocation = Get-Location;
$ScriptLocation = Split-Path $MyInvocation.MyCommand.Path
Write-Host "FilePath = [$FilePath]";
Write-Host "CurLocation = [$CurLocation]";
Write-Host "ScriptLocation = [$ScriptLocation]";
Results:
O:\Data>powershell ..\Script\t.ps1
FilePath = []
CurLocation = [O:\Data]
ScriptLocation = [O:\Script]
As to the differences between the various cmd.exe implementations, I can't really answer that. I should have thought they'd be functionally identical, but maybe there's 32/64-bit differences that matter.
The error occurs, when using PowerShell x32 and occurs NOT on PowerShell 64bit.
I debugged into the script using powershell_ise_x32 and found out, that $Word.Documents is null.
This is because on my system Word 64bit is installed.
I have downloaded SSH-Sessions by Joakim Svendsen which uses SSH.NET and installed the PowerShell module in the Jenkins Windows server
In Jenkins, I have the following PowerShell script:
Import-Module SSH-Sessions
$lastExitCode = 0
$devApp1 = "10.0.0.1"
$devApp2 = "10.0.0.2"
Write-Output "Deployment started in $devApp1......"
New-SshSession -ComputerName $devApp1 -Username test -Password test#123
$return = Invoke-SshCommand -ComputerName $devApp1 -Command "cd /NFS_DATA/autodeploy_scripts && echo test#123 | ./autodeploy.sh"
$return | Get-Member
if ($lastExitCode -ne 0)
{
Write-Output $lastExitCode
exit 1;
}
else
{
Write-Output $lastExitCode
exit 0;
}
The shell script contains:
#!/bin/bash
file="/NFS_DATA/autodeploy_scripts/test.log"
if [ -f "$file" ]
then
echo "$file found."
exit 0;
else
echo "$file not found."
exit 1;
fi
The problem is that the Jenkins job doesn't get failed when the file is not found. The Jenkins output is:
> Deployment started in 10.0.0.1...... Successfully connected to
> 10.0.0.01
> 10.0.0.01 had an error:
Finished: SUCCESS
After some suggestions I wrote the following PowerShell script using Posh-SSH. I'm also getting an error for this one, though it's different.
#Import-Module SSH-Sessions
Import-Module Posh-SSH
# Setup static variables
$devApp1="10.0.0.1"
$devApp2="10.0.0.2"
$username = "test"
$password = "test#123"
$command = "cd /NFS_DATA/autodeploy_scripts && echo Hybris#123 | ./autodeploy.sh"
Write-Output "Deployment started in $devApp1..."
# Setup PSCredentials
$secPasswd = ConvertTo-SecureString $password -AsPlainText -Force
$credentials = New-Object System.Management.Automation.PSCredential ($username, $secPasswd)
echo $credentials
# Estalbish new SSH session automatically accepting new SSH keys
$session = New-SSHSession -Computername $devApp1 -Credential $credentials -Acceptkey:$true
# Invoke command to be run on/in the SSH session
$output = Invoke-SSHCommand -SSHSession $session -Command $command
Write-Output "Returned Output from the Command: "
Write-Output $output.Output
Write-Output "Last Exit Status: "
Write-Output $output.ExitStatus
Getting the error message as:
The same code works in my local laptop, but fails in the Jenkins server.
I think in Jenkins server, due to Windows security restrictions, will not store the $secpasswd that is retrieved from the PSCredential. This causes only the username to be supplied to POSH.
How can I either fix those issues? How should I hardcode the password?
As you've never stated where those commands are coming from, I'm going to assume you're using Posh-SSH. By looking at this article about it, the solution would probably be:
$dev_app1="10.00.00.01"
$dev_app2="10.00.00.02"
echo "Deployment started in $dev_app1......"
Import-Module SSH-Sessions
New-SshSession -ComputerName $dev_app1 -Username test -Password test#123
$result = Invoke-SshCommand -ComputerName $dev_app1 -Command "cd /NFS_DATA/autodeploy_scripts && echo test#123 | ./autodeploy.sh"
Write-Output "Returned Output from the Command: "
Write-Output $result.Output
Write-Output "Last Exit Status: "
Write-Output $result.ExitStatus
if($result.ExitStatus -ne 0){
exit $result.ExitStatus;
}
The if could be left out, it's just there for demonstration purposes. After all the exit status would be 0 otherwise.
The correct way to use Get-Member to get information about $result (in case this does not work) would be: $result | Get-Member. That will output the general attributes of whatever kind of object $result is.
As it would appear you're running this. You would need to run the following to get the objects:
$result = $SshSessions."$dev_app1".RunCommand('cd /NFS_DATA/autodeploy_scripts && echo test#123 | ./autodeploy.sh')
You'd use this instead of the Invoke-SshCommand and would need to change $result.Output to $result.Result.
I have an autologon Powershell script that I'd like to run as admin when I double click on it. I tried to use different scripts but I'm out of luck.
For example:
Start-Process PowerShell –Verb RunAs
Would open another Powershell screen as administrator but without the original script that I wanna run which is:
net accounts /minpwlen:0
net user TPUser /add
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' -Name AutoAdminLogon -Value 1
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' -Name DefaultUserName -Value "TPUser"
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' -Name DefaultPassword -Value ""
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' -Name DefautDomainName -Value ""
copy c:\temp\OP.rdp c:\Users\Public\Desktop
pause
Any idea how can I get this to work ?
You are in luck because I was fighting with this issue for some time, what you need to do is make it take note of where it is at and when it starts back up the shell as an admin it needs to execute the script.
Function Test-IsAdmin {
[cmdletbinding()]
Param()
Write-Verbose "Checking to see if current user context is Administrator"
If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.NTAccount] "[WriteGroupHere]"))
{
Write-Warning "You are not currently running this under an Administrator account! `nThere is potential that this command could fail if not running under an Administrator account."
Write-Verbose "Presenting option for user to pick whether to continue as current user or use alternate credentials"
#Determine Values for Choice
$choice = [System.Management.Automation.Host.ChoiceDescription[]] #("Use &Alternate Credentials","&Continue with current Credentials")
#Determine Default Selection
[int]$default = 0
#Present choice option to user
$userchoice = $host.ui.PromptforChoice("Warning","Please select to use Alternate Credentials or current credentials to run command",$choice,$default)
#$workingDir = $PSCommandPath
#$PSCommandPath
Write-Debug "Selection: $userchoice"
#Determine action to take
Switch ($Userchoice)
{
0
{
#Prompt for alternate credentials
Write-Verbose "Prompting for Alternate Credentials"
$Credential = Get-Credential
#Write-Output $Credential
#We are not running "as Administrator" - so relaunch as administrator
Start-Process powershell.exe -ArgumentList "$PSCommandPath" -Credential $Credential
#-WorkingDirectory $workingDir
exit
}
1
{
#Continue using current credentials
Write-Verbose "Using current credentials"
Write-Output "CurrentUser"
}
}
}
Else
{
Write-Verbose "Passed Administrator check"
#$Host.UI.RawUI.WindowTitle = "Custom Powershell Environment" +
#$Host.UI.RawUI.BackgroundColor = "DarkBlue"
}
}
with this just put it in the top of your script and call the function, and you will need to change the group that it checks to know if you are an admin or not, I was using an AD group to check since it was a more functional way for me.
I have used the following before to re-launch as script as admin but there is not stopping the UAC prompt:
function IsAdministrator
{
$Identity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$Principal = New-Object System.Security.Principal.WindowsPrincipal($Identity)
$Principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
}
function IsUacEnabled
{
(Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System).EnableLua -ne 0
}
#
# Main script
#
if (!(IsAdministrator))
{
if (IsUacEnabled)
{
[string[]]$argList = #('-NoProfile', '-NoExit', '-File', $MyInvocation.MyCommand.Path)
$argList += $MyInvocation.BoundParameters.GetEnumerator() | Foreach {"-$($_.Key)", "$($_.Value)"}
$argList += $MyInvocation.UnboundArguments
Start-Process PowerShell.exe -Verb Runas -WorkingDirectory $pwd -ArgumentList $argList
return
}
else
{
throw "You must be administrator to run this script"
}
}
I actually used this script on top of mine and it worked perfectly.
# ##########################################
# Determine if we have Administrator rights
Write-Host 'Checking user permissions... '
$windowsID = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$windowsSecurityPrincipal = New-Object System.Security.Principal.WindowsPrincipal($windowsID)
$adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator
If (!($windowsSecurityPrincipal.IsInRole($adminRole))) {
Write-Warning 'Current user does not have Administrator rights'
Write-Host 'Attempting to copy files to temporary location and restarting script'
# Get random file name
Do {
$temp = [System.IO.Path]::GetTempPath() + [System.IO.Path]::GetRandomFileName()
} Until (!(Test-Path -LiteralPath "$temp"))
# Create directory
Write-Host 'Creating temp directory... ' -NoNewLine
New-Item -Path "$temp" -ItemType 'Directory' | Out-Null
Write-Host 'done.'
# Copy script to directory
Write-Host 'Copying script to temp directory... ' -NoNewLine
Copy-Item -LiteralPath "$($myInvocation.MyCommand.Path)" "$temp" | Out-Null
Write-Host 'done.'
$newScript = "$($temp)\$($myInvocation.MyCommand.Name)"
# Start new script elevated
Write-Host 'Starting script as administrator... ' -NoNewLine
$adminProcess = New-Object System.Diagnostics.ProcessStartInfo
$adminProcess.Filename = ([System.Diagnostics.Process]::GetCurrentProcess()).Path
$adminProcess.Arguments = " -File `"$newScript`""
$adminProcess.Verb = 'runas'
Try {
[System.Diagnostics.Process]::Start($adminProcess) | Out-Null
}
Catch {
Write-Error 'Could not start process'
Exit 1
}
Write-Host 'done.'
Exit 0
}