Poweshell Start-Job from serviceAccount using SailPoint IQService - windows

So there are several factors in play with this question, so here they are:
SailPoint 8.2 and IQService 8.2
Windows Server 2016
A service Account(Domain Admin)
An interactive User account (Domain admin)
Powershell 5.1 build 14393 revision 4583
So what we have is SailPoint is executing a rule on its end, sending over some information to IQService, and IQService is executing the PowerShell scripts as the service account. In one of the PowerShell scripts, we have the following command:
LogToFile("calling start job")
$j = Start-Job -ScriptBlock { C:/SailPoint/Scripts/PowershellContainerAfterCreateRetry.ps1 -sAMAccountName $args[0] -company $args[1] } -ArgumentList $sAMAccountName, $company -Name 'PowershellContainerAfterCreateRetry'
LogToFile($j | Select-Object -Property *)
LogToFile("finished start-job")
and this is where things get interesting because this command, as you can note, we can log to file to see what its output is, which is as follows:
calling start job
#{
State=Running; HasMoreData=True;
StatusMessage=;
Location=localhost;
Command= C:/SailPoint/Scripts/PowershellContainerAfterCreateRetry.ps1 -sAMAccountName $args[0] -company $args[1] ;
JobStateInfo=Running;
Finished=System.Threading.ManualResetEvent;
InstanceId=aa889c06-7a8a-402e-807a-880d02465bdd; Id=1;
Name=PowershellContainerAfterCreateRetry;
ChildJobs=System.Collections.Generic.List`1[System.Management.Automation.Job];
PSBeginTime=10/15/2021 21:14:22; PSEndTime=;
PSJobTypeName=BackgroundJob;
Output=System.Management.Automation.PSDataCollection`1[System.Management.Automation.PSObject];
Error=System.Management.Automation.PSDataCollection`1[System.Management.Automation.ErrorRecord];
Progress=System.Management.Automation.PSDataCollection`1[System.Management.Automation.ProgressRecord];
Verbose=System.Management.Automation.PSDataCollection`1[System.Management.Automation.VerboseRecord];
Debug=System.Management.Automation.PSDataCollection`1[System.Management.Automation.DebugRecord];
Warning=System.Management.Automation.PSDataCollection`1[System.Management.Automation.WarningRecord];
Information=System.Management.Automation.PSDataCollection`1[System.Management.Automation.InformationRecord]}
finished start-job
When I execute this command either by itself OR within this script using Windows PowerShell ISE, it completes with no issue and calls the script in question, and everything works perfectly! (whether I am using my interactive account OR the service account)
When this script executes using the IQService, something "else" is happening - I say something "else" because I don't have any log files or errors; it just seems to disappear into the ether. (I have a log write out five lines into the PowerShell script, so one would think I would at least get SOMETHING!?!? I am out of ideas...thoughts?
As a minor note, I ran an experiment that showed me that there is something strange about the setup which should have succeeded without issue - like the above it appears to execute (because I can see the same information above, that shows that the job has started). Still, just like the above, it never actually "appears" to complete or error out. The only thing I can think of is that somehow the primary script closing out is causing this to close out as well - but I would think it would be able to get a couple of log files written to if that was the case? Anyway...thanks for reading!
$doit = {
"test" | Out-File -filepath ("c:\test.txt") -append
}
Start-job -ScriptBlock $doit

i think Start-Job is the problem here, as iqservice will launch a powershell script process and that may not support the background job aspect you are trying to use.
if you need to have something retry or wait and loop, you'll need to use another identityiq/iqservice mechanism (a workflow in iiq perhaps that calls down to AD when conditions are, timer is hit, etc.) beyond start-job inside of an iqservice powershell script.

Related

How to start long-running/background process from PowerShell completion mechanism?

I have a PowerShell completion hook that looks like:
$scriptblock = {
param($wordToComplete, $commandAst, $cursorPosition)
# ...
clap-json-test-completions power-shell query $wordToComplete $script:index -- #elements | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_)
}
}
Register-ArgumentCompleter -Native -CommandName clap-json-test -ScriptBlock $scriptblock
The clap-json-test-completions command is a program written in Rust which generates suggestions for the completing the current command line.
The clap-json-test-completions program is designed to talk to a local "server" process on the machine for certain bits of information that take longer to figure out and can be cached by the server process. If the server process isn't running then the clap-json-test-completions program attempts to start it up.
Unfortunately, the PowerShell completions mechanism waits until that server process stops before returning the suggestions to the user. As that server process is designed to not stop, this is an issue.
I have tried spawning the server process using:
.creation_flags(
DETACHED_PROCESS_FLAG
| CREATE_NEW_PROCESS_GROUP_FLAG
)
Based on the Creation Flags documentation in the Windows docs. Unfortunately they don't seem to have to desired effect. Instead of allowing the completion process to return whilst the server is still running, they just seem to make it so that Ctrl-C no longer kills the server from the hung completion prompt.
I've also tried launching the command a "Job" using:
Start-Job -ScriptBlock { clap-json-test-completions power-shell query $wordToComplete $script:index -- #elements } | Receive-Job -AutoRemoveJob -Wait | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_)
}
In the Power-Shell completion script and using CREATE_BREAKAWAY_FROM_JOB_FLAG as an additional creation flag but that doesn't seem to work.
I understand that Windows Services exist for long running processes but we would rather have a situation where the server only starts when the user first tries to do a completion and have a situation where the user has permissions to start the server (as a normal process) rather than requiring extra permissions to interact with the Windows Service system.
The current approach works fine if the clap-json-test-completions binary is run by itself outside of the completions system. It doesn't hang waiting for the server to finish.
Is there an approach to either the PowerShell completion script or the process creation in the Rust code that'll allow the completion system to return whilst the server still runs?

Autologon.exe via command line and get result

Is there a way I can execute sysinternals Autologon.exe from command line (Powershell) and get the result, i.e. know if the credentials entered were correct?
If I use the GUI and not the command line then I do get message with this info..
Thanks.
You can run any Windows .exe/cmd/bat/vbs from PoSH, as long as you call it correctly.
PowerShell: Running Executables
https://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx
There are several different methods for running executables as well as invoking code. How do you know which one to use for the job? Here is an outline of the methods with examples and general use.
Regarding ---
"If I use the GUI and not the command line then I do get message with this info.."
This is because Autologon.exe is doing this work and returning the result. SO, it's Autologon. PoSH will not get in Autologon's way / process, but you can get the exit code from external tools as long as you know what they are. I've not tried to this with Autologon. Yet, in most cases, it's a Boolean response: success or failure, 0 or 1, or 1 or 2. The Start-Process cmdlet allows you to trap error / exit code from a process, using the -PassThru parameter. Often that is use in concert with the -wait parameter as well.
Something like:
$AutologExitCode = Start-Process -FilePath = Autologon.exe -ArgumentList $SomeArguments -NoNewWindow -Wait -PassThru
"The error/exit code from AutoLogon is $($AutologonExitCode.ExitCode)"
Full disclosure: We do not allow Autologon in our environment. So, I've spent no time using Autologon, but the above premise would be the same as other exe's.

remote execution(PowerShell) of cmd file doesn't complete

Current PS script:
Invoke-Command -ComputerName RemoteServer007.FQDN.com -ScriptBlock {
Set-Variable -Name WOWCONFIG -value "d:\ABCs\WOWzers" `
| Start-Process "d:\da-folder\Do-It-NOW-Pleez.cmd"
}
If I log on locally to the server(RemoteServer007.FQDN.com) and execute the cmd file, it runs through all of the lines(commands) within the cmd file.
When I execute it remotely, it gets about 30% of the way through the commands within the cmd file, the PS execution ends without error, but not all of the lines/commands in the cmd file had been executed.
This was discovered by simply configuring each line of the cmd file to output to txt files.
I even tried re-ranging the commands in the cmd file, thinking that perhaps there was a specific command that was causing it to exit, but that is not the case.
I'm wondering if there is some timeout or response that PowerShell is not getting? and just quitting almost immediately after starting?
Any ideas or help would be greatly appreciated.
There are a couple of things you can do here:
You may have a memory issue. Increasing the value of MaxMemoryPerShellMB might help
set-item WSMan:\$target\Shell\MaxMemoryPerShellMB -Value 0 -Force
You'd need to run this once on the remote machine before you execute your commands again.
You can also see possible error logs in the windows event viewer. There are categories for powershell and for Windows Remote Management which you should look at.
Finally, you can just run this process asynchronously, using the task scheduler for instance. I had a similar problem with windows in the past, and running the process from the task scheduler, outside the powershell session, fixed it. There's an example of how we did this in Cloudify here:
https://github.com/CloudifySource/cloudify/blob/master/esc/src/main/resources/clouds/ec2-win/upload/bootstrap-management.ps1#L220

Register-ScheduledJob and Write-Host

I'm using Register-ScheduledJob to register job in powershell in background job I execute script. This script contains some commands like Get-Process and Write-Host command. And...
Altough every command is executed in results I don't see outputs from write-hosts (get-Process is is ok)
Maybe someone know why?
Write-Host writes to the host, which is the app that the script is running in (PowerShell.exe for instance), so it is output explicitly to the screen, and DOES NOTHING when you're running in a non-interactive environment. You should never use that to output data that you want to collect, only for lightweight debugging or for printing to the screen in interactive scripts.
You should generally use write-output for the data that you want to collect as output.
Although you can also use the debug/warning/error output (those are collected by the job, but not shown in the regular output).
Thank You very much. Write-Output helped.
Additionaly what i discover during last days and could be helpful for others: if you start scheduled background job and in this job start powershell script like this:
Register-ScheduledJob -Name1 temp -ScheduledJobOption $option -ScriptBlock {
D:\scprit.ps1
}
Your job will never end because after finish script powershell window is still open. So additionaly you have to add exit in your scriptblock:
Register-ScheduledJob -Name1 temp -ScheduledJobOption $option -ScriptBlock {
D:\scprit.ps1
Exit-PSSession
}

Powershell remote session external command execution

I've been playing around with powershell remoting and I've come across a problem that I am unable to resolve. I have a script that creates a remote session and after setting up some variables does the following:
Invoke-Command -Session $remote_session -ScriptBlock $block -ArgumentList $args
Within the block everything works fine except when it comes to a specific line, at which point the script hangs. The pertinent line is:
& '.\external_command.exe' $argument_list
When I log into the computer that is hosting the remote powershell session I can see external_command.exe in the process list but it's not doing anything. Does anyone have any ideas on how to resolve the issue?
I had similar problems with remote execution of installers. As a workaround I now first create a cmd batch file through powershell and then run this batch file. Something like this:
"c:\external_command.exe argument1" > c:\run.cmd
&"c:\Run.cmd" |Out-Null

Resources