Get the current ScheduledJob name - powershell

In Powershell, I created a ScheduledJob using the command Register-ScheduledJob -ScriptBlock {...}. This ScheduledJob executes a ScriptBlock. How can I retrieve the name of the currently running ScheduledJob from the ScriptBlock?
E.g.
Register-ScheduledJob -ScriptBlock { $CurrentScheduledJob | Out-File -FilePath ScheduledJob.txt}
The task in the Windows Task Scheduler is running the command:
powershell.exe -NoLogo -NonInteractive -WindowStyle Hidden -Command
"Import-Module PSScheduledJob; $jobDef =
[Microsoft.PowerShell.ScheduledJob.ScheduledJobDefinition]::LoadFromStore('asdfdsafsdf',
'C:\Windows\system32\config\systemprofile\AppData\Local\Microsoft\Windows\PowerShell\ScheduledJobs');
$jobDef.Run()"
I tried to save the variable $jobDef but it is empty.
Thank you

I ran a ScheduledJob and exported all variable and environment variable and did not find the name or id of the job.
I found a work around:
$jobName = 'testName'
Register-ScheduledJob -ScriptBlock { param($name)
$name | out-file C:\name.txt
} -name $jobName -ArgumentList #($jobName)
If using a parameter is not a solution for you, and you absolutely must retrieve it at run time, then this is a feature request. You can ask for this at the PowerShell user voice

Related

Call PowerShell script with argument from another Powershell script with bypass

I need to call a ps1 Script during going through another ps1 file. The new call shouldn't interrupt the script which I'm going through. Also I always call the Powershell scripts like this: powershell -ExecutionPolicy Bypass -File file.ps1 -param log_14.txt due to execution policies.
I tried following code in my .ps1 script, sadly it doesn't work:
Start-Job PowerShell -Argument "sort.ps1 -file $fileName"
Any ideas how to make it work?
Try this:
$job = Start-Job -ScriptBlock {
powershell -ExecutionPolicy Bypass -File "filepath.ps1 Param"
}
$job | wait-job | receive-job

Using Invoke-Command to run Start-Process in an elevated session

As a precursor to running an installation file on several remote servers, I need to update the Powershell setting MaxMemoryPerShellMB. This requires running a PS session as Administrator on the remote server. I have been trying to run Invoke-Command which then runs a ScriptBlock consisting of a Start-Process command which includes the -Verb RunAs parameter. Nothing seems to work, however.
I have tried with various quoting schemes, single, double, triple, but nothing seems to work.
I've tried running the Start-Process from an Enter-PSSession, with the same results.
Following is the code I'm testing now:
$creds = Get-Credential -Username 'DOMAIN\userID' -Message "Enter Username and Password to access the remote servers."
$ScriptBlock = {
Start-Process -FilePath Powershell.exe -ArgumentList """Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB 1024""" -Verb RunAs -Wait
}
Invoke-Command -ComputerName testsvr01 -Credential $creds -ScriptBlock $ScriptBlock
I should be able to RDP to the remote server and run Get-Item WSMan:\localhost\Shell and have it show the updated value, but the value isn't changed.
When running the code it pauses for a second when the Invoke-Command runs, but other than that, there is no feedback in Powershell.
On the remote server I see the following two Kerberos errors in the System Event log.
0x19 KDC_ERR_PREAUTH_REQUIRED,
0xd KDC_ERR_BADOPTION
Any help is greatly appreciated.
> powershell.exe -?
...
EXAMPLES
...
PowerShell -Command "& {Get-EventLog -LogName security}"
-Command
...
To write a string that runs a Windows PowerShell command, use the format:
"& {<command>}"
where the quotation marks indicate a string and the invoke operator (&)
causes the command to be executed.
So you could try to call Set-Item in the following way:
$ScriptBlock = {
Start-Process -FilePath Powershell.exe -ArgumentList "-Command"," &{ Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB 1024 }" -Verb RunAs -Wait -PassThru
}
$process = Invoke-Command -ComputerName testsvr01 -Credential $creds -ScriptBlock $ScriptBlock
$process.ExitCode
I'm also returning a process object via -PassThru on which you might check the `ExitCode``
Hope that helps

Why am I unable to make the external script run in a new window?

I built a powershell form that recreates a VM from a snapshot in azure. I have the backing script that does the actual work prepared and it works just fine on its own when I run it. But, when I go to execute it from within the script that generates the form, it either doesn't run or it gets stuck relatively early on in the file and does not complete execution of all the commands. I can validate the parameters are correct when I run it, as one of the buttons on the form calls a different script that validates all of the parameters.
Since one of the subscripts keeps getting stuck in execution, I want to open it in a new window and leave it to finish. However everything I've tried to do either:
doesn't run the script
opens a new window but does nothing
opens then immediately closes the script (i don't see red text in the second it runs). Since total execution is normally 10 minutes, I know it's either crashed or rage-quit on me.
I've also noticed that when I run azureRM commands from within a form, that if I try to execute more than 2 commands to do something it immediately freezes the script regardless of whether or not I open this in ISE or run from CLI. in the snip below, this is what I'm trying to run when i click the button to renanimate/recreate the VM. You'll see that I've commented out a LOT of attempts to make it run on its own.
$reanimateButton.add_Click({
$mySub = ""
if($RadioButton1.Checked){$mySub = '$subscriptionA'}
if($RadioButton2.Checked){$mySub = '$subscriptionB'}
$rgName = $rgMenu.Text
$vm = $vmNameMenu.Text
$sa = $storageMenu.text
$oSnap = $snapOSMenu.Text
$dSnap = $snapDataMenu.Text
$opSnap = $snapOptionalMenu.Text
$vmSize = $vmSizeMenu.Text
$argumentList = "-subscription $mySub -resourceGroupName $rgName -vmName $vm -diagStorageAcc $sa -snapshotName $oSnap -DataSnapshotName $dSnap -optionalDataSnapName $opSnap -vmSize $vmSize"
$scriptPath = "C:\azure\vm scripting\Reanimator\Restore-vmFromSnapshot.ps1"
#cd "C:\azure\vm scripting\Reanimator"
#.\Restore-vmFromSnapshot.ps1 -subscription $mySub -resourceGroupName $rgName -vmName $vm -diagStorageAcc $sa -snapshotName $oSnap -DataSnapshotName $dSnap -optionalDataSnapName $opSnap -vmSize $vmSize
#Invoke-expression 'cmd /c start powershell -Command {"& `"$scriptPath`" $argumentList"}'
#Invoke-Expression "& `"$scriptPath`" $argumentList"
cmd /c start powershell -Command {"& `"$scriptPath`" $argumentList"}
#start-process powershell -ArgumentList -NoExit -Command {cd "C:\azure\vm scripting\Reanimator"; .\Restore-vmFromSnapshot.ps1 -subscription $mySub -resourceGroupName $rgName -vmName $vm -diagStorageAcc $sa -snapshotName $oSnap -DataSnapshotName $dSnap -optionalDataSnapName $opSnap -vmSize $vmSize;}
})
DO NOT use Invoke-Expression.
For starting a PowerShell script or command in a new window use Start-Process. The reason why your attempt at that didn't work is most likely that PowerShell interpreted -NoExit and -Command as parameters for Start-Process (which don't exist) rather than as arguments for the new PowerShell process. You need to pass the arguments either as a single string
Start-Process 'powershell.exe' -ArgumentList "-NoExit -Command {...}"
or as an array where parameters like -NoExit should be defined as strings.
Start-Process 'powershell.exe' -ArgumentList '-NoExit', '-Command', "{...}"
With that said, your statement is overly convoluted. A better (simpler) approach is to set the working directory via the respective Start-Process parameter and then run the script via -File.
$workdir = 'C:\azure\vm scripting\Reanimator'
$params = '-NoExit', '-File', '.\Restore-vmFromSnapshot.ps1',
'-subscription', $mySub, '-resourceGroupName', $rgName,
'-vmName', $vm, '-diagStorageAcc', $sa, '-snapshotName', $oSnap,
'-DataSnapshotName', $dSnap, '-optionalDataSnapName', $opSnap,
'-vmSize', $vmSize
Start-Process 'powershell.exe' -WorkingDirectory $workdir -ArgumentList $params

How can I run powershell in the background if I want execution policy Bypass?

I have this batch file which runs the powershell script.
I want to run it the background but if I run with "windowstyle hidden" still visible.
powershell -ExecutionPolicy ByPass -windowstyle hidden -File "C:\script.ps1"
You can run, e.g. long running scripts, as a jobs.
To start it you run
$job = Start-Job -ScriptBlock {Get-Process}
this will start the Get-Process cmdlet in the background. The script can be also some custom made script or a longer script, it doesn't need to be a one-liner.
You can check its status by running
$job | Get-Job
and to receive the output you run
$job | Receive-Job
just note that once the data is received, it's lost. You can only receive it once, after that it's up to you to save it in a variable or later processing.
Finally to remove the job from the queue you run
$job | Remove-Job
I use the following function:
function bg() {
Start-Process `
-WorkingDirectory (Get-Location) `
-NoNewWindow `
-FilePath "powershell" `
-ArgumentList "-NoProfile -command `"$args`" "
}
It starts a new powershell instance which is executed in background and allows the usage of cmdlets.
You call it like:
bg "Start-Sleep 2; get-location; write 'done' "

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}"