I have a powershell script that I am trying to run at computer startup through a GPO using the new tab for powershell scripts that can be found in the group policy editor.
No matter what, it does not seem to be running at all, and I suspect the problem might for some reason be with the script itself using some var or calling to something that is not available under NT Authority\System impersonation.
Should something in the following script need to be edited in order to actually work as a startup script via GPO?
$sysdrivelocker = Get-BitLockerVolume -MountPoint $env:SystemDrive
#If the drive is encrypted and ready, exit script and do nothing.
if(($sysdrivelocker.VolumeStatus -eq "FullyEncrypted") -or ($sysdrivelocker -eq "EncryptionInProgress")){
exit
}
#If the drive has been prepared with bdehdcfg, start bitlocker encryption and restart the computer.
else if($sysdrivelocker.VolumeStatus -eq "FullyDecrypted"){
#Creating the recovery key
Start-Process 'manage-bde.exe' -ArgumentList " -protectors -add $env:SystemDrive -recoverypassword" -Verb runas -Wait
#Adding TPM key.
Start-Process 'manage-bde.exe' -ArgumentList " -protectors -add $env:SystemDrive -tpm" -Verb runas -Wait
sleep -Seconds 15 #This is to give sufficient time for the protectors to fully take effect.
#Getting Recovery Key GUID.
$RecoveryKeyGUID = (Get-BitLockerVolume -MountPoint $env:SystemDrive).keyprotector | where {$_.Keyprotectortype -eq 'RecoveryPassword'} | Select-Object -ExpandProperty KeyProtectorID
#Backing up the Recovery to AD.
Start-Process 'manage-bde.exe' -ArgumentList " -protectors $env:SystemDrive -adbackup -id $RecoveryKeyGUID" -Verb runas -Wait
#Enabling Encryption.
Start-Process 'manage-bde.exe' -ArgumentList " -on $env:SystemDrive" -Verb runas -Wait
#Restarting the computer, to begin the encryption process.
Restart-Computer
}
#If the drive is not bitlocker ready, prepare it and restart the computer.
else if([string]::IsNullOrEmpty($sysdrivelocker.VolumeStatus) -eq $true)
#Starting the defrag service, required in the next step.
Get-Service -Name defragsvc -ErrorAction SilentlyContinue | Set-Service -Status Running -ErrorAction SilentlyContinue
#Preparing the systemdrive for bitlocker activation, and restarting the computer.
BdeHdCfg -target $env:SystemDrive shrink -quiet -restart | Out-Null
}
#Exit in case the volume status is anything else (e.g. paused or decryption in progress).
else{
exit
}
And yes, before anyone asks, I have set it up correctly as any guide I could find tells me, the script is located under \\domain.local\SysVol\domain.local\Policies\{GPO-GUID}\Machine\Scripts\Startup and for troubleshooting purposes I even set my machines execution policy to unrestricted.
Related
$serviceName = "wsearch"
$isRunning = Get-Service | Where-Object {$_.Status -eq "Running" -and $_.Name -eq $serviceName}
$isStopped = Get-Service | Where-Object {$_.Status -eq "Stopped" -and $_.Name -eq $serviceName}
if ($isStopped) {
Start-Service -InputObject $isStopped
Start-Sleep -s 10
}
if ($isRunning) {
Stop-Service -InputObject $isRunning
Start-Sleep -s 10
}
I want to run this script, but I don't want to set Administrator execution policy (which is set to max restrictive), while regular user policy is lax.
I want to run the script as a regular user and trigger the UAC prompt for each command (akin to -Verb RunAs), however, Start-Service does not accept this parameter.
I guess I can run a Start-Process "sc" but that defeats the purpose of powershell.
The ultimate goal of the script is to swtich the state of a service based on the current running state.
There is no way to run one-off commands elevated (as admin) in a non-elevated powershell session. This would be similar to 'sudo' in Linux which just doesn't exist in the Windows world. Instead you could use something like the following to start a powershell session as administrator and run the commands there. You are not limited to calling 'sc'
Start-Process -Verb RunAs -FilePath 'powershell' -Arguments '-Command <your commands>'
To run a powershell script with elevated privileges you could substitute -Command for -File (but -Command <path to file> will also work)
Start-Process -Verb RunAs -FilePath 'powershell' -Arguments '-File <path to script>'
I tried to run a Powershell Script under the System Account via Jenkins.
$DebugPreference = 'Continue'
$dt=get-date -Format "MM-dd-yyyy-HH-mm-ss-fff"
Start-Transcript -Path "C:\install\transcript-$dt.txt"
dir env:
$cmdline = $((Get-CimInstance win32_process -Filter "ProcessID=$PID" | ? { $_.processname -eq "pwsh.exe" }).commandline)
if($cmdline -like "*pwsh.exe*")
{
write-host "Powershel 7 continue"
Write-Host "Before Start-session"
$s = New-PSSession -HostName ip -UserName user -verbose -KeyFilePath C:\.ssh\id_rsa
Write-Host "After Start-session"
}else{
Start-Process pwsh.exe -Wait -PassThru -ArgumentList "-NonInteractive -ExecutionPolicy Bypass -File $($MyInvocation.MyCommand.Definition)"
}
stop-transcript
My Problem is that Write-Host "After Start-session" is never reached.
The first Start-Transcript shows, that the Script is started again with pwsh.exe
The second Start-Transcript shows the Output till Before Start-session.
After that there is nothing added to the Transcript and the Process keeps running.
The Script is working fine, when it is running under the Administrator Account.
How can I debug this ?
The Problem was that the SSH fingerprint was not trusted.
When I runned the Script via a command Line instead of via Jenkins direct, i got this output:
The authenticity of host 'ip (ip)' can't be established.
ECDSA key fingerprint is SHA256:gQv8WE8G04RhfNNX7pRQjVX0lPj3jNZ4JTPIDNEIGHk.
Are you sure you want to continue connecting (yes/no)?
After i answered it with yes everything worked.
The Jenkings Job is now working two.
Context: IT staff may or may not log in with a local administrator account and run the following script. Due to the way Windows credential caching works on a local admin account, a simple copy and paste of the files without hardcoded credentials from a UNC path may not work occasionally.
My workaround for this issue was to just create a PSDrive for the session using a set of credentials that are reserved exclusively for scripting and domain joins.
IT staff access this script from the same server (fileserver05). The script attempts to make a temporary map of fileserver05. Is it just looping and confusing itself, or what?
Function Install {
Start-Process net -wait -ArgumentList "use X /delete" -ErrorAction SilentlyContinue
Remove-PSDrive X -Force -ErrorAction SilentlyContinue
Try {
$agentPass = Read-Host -AsSecureString -Prompt "Deployment operations supervisor password"
$agentUser = 'domain.com\agent'
$agentCred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $agentUser,$agentPass
New-PSDrive -Name "X" -PSProvider "FileSystem" -Root "\\fileserver05\Fileserver05\IT\Programs\Windows\Yardi CHECKscan Client" -Credential $agentCred -ErrorAction Stop
Write-Host 'Deploying CHECKscan client to local machine...'
Copy-Item -Path "X:\install.msi" -Destination "${env:TEMP}" -Force
Start-Process msiexec -Wait -ArgumentList "/i `"${env:TEMP}\install.msi`" /qn /norestart"
Write-Host 'Deploying connection settings to current and default user profile...'
Copy-Item -Path "X:\yCheckSettings.xml" -Destination "${env:APPDATA}" -Force
Copy-Item -Path "X:\yCheckSettings.xml" -Destination "C:\Users\Default\AppData\Roaming" -Force
}
Catch {
Write-Host ""
Write-Host "An error occured during installation" -BackgroundColor Red -ForegroundColor White
Write-Host "Ensure you have the correct credentials and a connection to the corporate network"
Write-Host "Ensure that paths to the installation files have not changed on the fileserver"
Write-Host ""
Install
}
}
Install
Please also note that ExecutionPolicy is set to Unrestricted.
If a staff member runs the script from the server, it fails and is unable to map the drive, therefore making the rest of the script not work. If a staff member takes the script and drags it to the local desktop, then runs it, it succeeds.
How can I make it so it can be ran from the server itself?
I'm creating a powershell script to import Dynamics NAV Application Objects to my Dynamics NAV 2018 database.
Microsoft is providing a PS cmdlet - Import-NAVApplicationObjects - to do so, but I have trouble to wait for the command to finish.
I have a calling script which does the following
$PSSession = New-PSSession -ComputerName $TargetMachine -Credential $MyCredential
Invoke-Command -Session $PSSession -ArgumentList $Database_Name_user, $MyCredential -ScriptBlock {
$process = Start-Process powershell.exe -Verb RunAs -Wait -PassThru -ArgumentList "-File `"C:\Users\User\Desktop\Database\Import1.ps1`" $args[0]"
$process.WaitForExit()
if ($process.ExitCode -ne 0) {
throw $process.StandardError.ReadToEnd()
}
}
The script Import1.ps1 on my $TargetMachine looks like this
param(
[String]$Database_Name_user
)
try {
$AllFiles = "C:\Users\User\Documents\AllFiles.txt"
$Modules = "C:\GIT\Loading Components\NAVModuleImport.ps1"
$OutputBuffer = import-module $Modules
Import-NAVApplicationObject -Path $AllFiles -DatabaseServer "SQLSRV001" -DatabaseName $Database_Name_user -SynchronizeSchemaChanges "No" -ImportAction "Overwrite" -Confirm:$false | Out-Null
}
catch{
$_ | Out-File "C:\Users\User\Documents\Import1.txt"
}
The file AllFiles.txt has a size of 220 MB and contains more than 7700 Dynamics NAV Application Objects (tables, pages, codeunits and so on).
When I launch the script which executes Import-NAVApplicationObject directly from the remote computer stored in $TargetMachine everything works smootly and the process takes up to 10 to 15 minutes, as expected.
When calling the script as shown in the first code example the output stops for a minute and then says everything is done.
Any help is appreciated, thank you in advance.
Edit: Solution
I noticed that my scripts as shown are working, the Import-NAVApplicationObjects cmdlet just failed.
When I elevate the powershell process on the remote computer and run the import, the cmdlet tried to authenticate as NT-Authority\Anonymous to the database.
Then I passed the credentials of the user that opens the remote PSSession to Import1.ps1 and used the parameters -UserName and -Password of the import cmdlet.
Sadly this process failed again.
Now I tried some things with the user I want to use for authenticating, changing passwords etc and it worked! The password contained a semicolon ; and apparently the import cmdlet was not happy with that.
So my simple solution is: Removing the semicolon from the password.
I have a script to uninstall McAfee antivirus and the agent associated with it.
The issue i'm having is that the script provides an exit code too early and doesn't continue through. If I run the script multiple times I get the desired result, but as we're trying to push it out via PDQ remotely, we need it to run through the script and only provide an exit code at the end of the script.
I'm a powershell novice so there's probably a much better and easier way to write this script but any advice would be greatly appreciated.
Start-Process -FilePath "msiexec.exe" -ArgumentList "/x {CE15D1B6-19B6-4D4D-8F43-CF5D2C3356FF} REMOVE=ALL REBOOT=R /q"; Write-Host "Uninstalling McAfee VirusScan Enterprise 8.8..."
$version = (Get-WmiObject -class Win32_OperatingSystem).Caption
Write-Host "Detected OS as $version"
if ($version -like '*Windows 7*')
{
Write-Host "Uninstalling McAfee Agent..."
Start-Process -FilePath "C:\Program Files (x86)\McAfee\Common Framework\frminst.exe" -ArgumentList "/forceuninstall"
}
elseif ($version -like '*Windows 10*')
{
Write-Host "Unmanaging McAfee Agent for Uninstall Process.."
Start-Process -FilePath "C:\Program Files\McAfee\Agent\maconfig.exe" -ArgumentList "/provision /unmanaged";
Write-Host "Uninstalling McAfee Agent..."
Start-Process -FilePath "C:\Program Files\McAfee\Agent\x86\frminst.exe" -ArgumentList "/forceuninstall"
}
else
{
exit
}
Start-Process reports a return code as soon as it starts the process indicating whether it was successful or not. Either use -wait to force the script to wait until it finishes or capture the output and proceed based on what the returnvalue is. See the docs for Start-Process