I recently "inherited" a complex PowerShell script that performs tasks in the background via task scheduler. Now we're seeing that the script hangs in some occasions, but until now I'm unable to identify the root cause.
Is there a way to pol or attach a debugger to an already running script so i can get the current line-number without rewriting large portions? In it's current state, the maintainability of the script is sub-par with 20k lines of code.
I tried checking WMI for properties, but found nothing useful. I did found a chronograph script that may be useful https://powershellexplained.com/2017-02-05-Powershell-Chronometer-line-by-line-script-execution-times/ .
I also wrote a debugging wrapper, but the hang only happens in some occasions. I am unable to reproduce on demand.
Thanks
Have you looked at Enter-PSHostProcess ?
The Enter-PSHostProcess cmdlet connects to and enters into an interactive session with a local process. Instead of creating a new process to host PowerShell and run a remote session, the remote, interactive session is run in an existing process that is already running PowerShell. When you are interacting with a remote session on a specified process, you can enumerate running runspaces, and then select a runspace to debug by running either Debug-Runspace or Enable-RunspaceDebug
Enter-PSHostProcess
Related
Thanks for stopping by, I've searched the corners of the internet but haven't gotten anywhere.
To provision devices for my organization, we must manually run PowerShell commands using SHIFT + F10 in the Windows 11 OOBE as we have multiple methods, one of which being legacy. I'm sure there are better methods but I'm unfortunately working within these limitations. So far, to automate the imaging process, I've created an autounattend.xml which makes WinPE completely silent and some pages of the OOBE also.
Recently, I combined all the PowerShell commands we had been running prior into a script that, after running repeated checks for a network connection, prompts users with a GUI and effectively automates everything we had been doing manually before:
Message box with radio buttons
I need to make this run when the OOBE Sysprep starts, but I really need some help.
The script contains GUI, so it cannot run silently and the user needs to interact with it.
The script must start with the OOBE Windows Welcome Screen, (i.e. select region screen). This is a limitation of the modules used and I therefore can't include it as a synchronous command in FirstLogonCommands or include it in SetupComplete.cmd, as those both execute after the OOBE is completed.
I've tried configuring the answer file to boot into audit mode and have the script run there, but the script requires several reboots and I get an installation failed message after any reboot (despite later making the script enable the Administrator account and call "sysprep /audit /reboot"). Additionally, the Audit Administrator account takes ~15 minutes to log in so it defeats the whole purpose of time saving.
I've tried using Task Scheduler, running both on System Start Up and User Log On, as defaultuser0, BUILTIN\Administrators and SYSTEM. Task scheduler seems to either queue tasks or not call them at all in the OOBE
I've tried placing the script, and then a shortcut of the script, in the common start up folder but that didn't work either.
To reiterate, I need a way to automatically run a script when the OOBE Sysprep starts. Furthermore, I need it to run every time the OOBE is launched as sometimes, we have to manually reboot if something glitches or goes wrong so the script will need to run again when the OOBE is resumed.
I know this is a tough one due to the limitations, but this will make the device rollout significantly easier.
Thanks,
Jake
We're having a very strange behaviour that I'm unable to identify a root cause for. We use TFS (2017.U2) to compile our legacy system, and are trying to update our build farm from 2008R2 up to 2016. The build system uses PowerShell (v5) to cycle through a list of VBP projects and run a VBS script to compile the projects.
First a bit of basics. UAC is totally disabled (in the registry, not just the slider control), VB6.EXE is also set to XP SP3 compatability, and also to run as the administrator.
Unfortunately, while we can see VB6.EXE start in task manager - it just hangs. Zero activity. Running the same compile interactively works just fine with the same user. This led me to theorize it was an environment problem, however process explorer shows me a valid user environment on the VB6.EXE process.
I don't believe this is due to VB6 throwing an error, as (at least in previous versions of Windows Server) when a background process opens a UI element, the OS indicates to the foreground that the background wants to break in. We dont see that.
We've stubbed this back to a bare minimum code example which I call "test.ps1":
$vb6="C:\Program Files (x86)\Microsoft Visual Studio\VB98\vb6.exe"
Set-Location D:\Builds\27\s\path\prjdir
start-process $vb6 -ArgumentList "/make /out errors.txt project.vbp" -wait
We've been using "start-process" to trigger the VB6 compiles because direct invokation via PowerShell doesn't ingest the parameters properly (they're actually built out of strings passed into the master script in the full blown process... this is the simplified version).
When run interactively (.\test.ps1) this functions properly. The project compiled and I get an errors.txt file written.
When started as a process (start-process .\test.ps1) this again functions properly.
When triggered via a TFS "PowerShell Script" task, this fails to complete the VB6 step - the VB6.EXE can be seen in the Task viewer with the appropriate arguments, and no CPU or IO is associated with the task. No errors.txt file is written. No new DLL is created.
I was able to dummy this down even further and remove TFS from the stack by running the test script from another machine. I ran a remote invokation of the script, and duplicated the result using this command:
PS C:\Users\svc_build> Invoke-Command –ComputerName TestBuild02 –ScriptBlock {powershell C:\Users\svc_build\desktop\test.ps1 }
Again, no errors.txt, and no new DLL. VB6.EXE starts up and just sits there. Process monitor doesnt provide any help in diagnosing what might be the issue.
This now smells of a security door being shut on me - even though the same domain user is running the same job, the difference is that this is a background process... and something is preventing a background process of executing in the same context as a foreground process.
Assuming this assumption is correct, can someone point me at the reason a remotely triggered (background) session isn't able to run VB6.EXE? (and of course, a work around for the situation would be appreciated :) )
If this is not a security issue - can someone identify the real culprit, and the solution to getting VB6 running as a background process, like we're used to seeing it run on W2K8R2?
I'm a bit late to the party, but this sounds like a very similar scenario to what I've just encountered.
Windows 10 v2004
UAC disabled
Compiling by running VB6.exe via a PowerShell script.
Using Bamboo as the build server, running as a Managed Service Account.
When running the build on the server via Bamboo, it hangs. When logging into the build server and running the build manually, it succeeded.
After cutting down the code I was able to reproduce a minimal failing case. The hang was caused by code in a UserControl's UserControl_Initialize method that was manipulating UI controls, but only when that UserControl was placed on a Form in the same project.
During compilation, the compiler will create an instance of the Form (why, I don't know), which in turn creates an instance of the UserControl, which in turn runs the UserControl_Initialize method. I can only assume that running the code at that point resulted in an error of some sort, and that resulted in the compiler hanging.
The same error can be caused by the UserControl_Resize event. That case is reasonably easy to fix by checking if Ambient.UserMode is true before trying to resize the child controls.
Private Sub UserControl_Resize()
If UserControl.Ambient.UserMode Then
' Position the child controls
End If
End Sub
Fixing the UserControl_Initialize methods required the code in those methods to be run at a different point (for example, when the UserControl is given the data to display, we now run the code that was previously in UserControl_Initialize).
Also worth noting is the compatibility settings for VB6.exe that we had to use. Using "Windows XP SP3" compatibility mode resulted in VB6.exe hanging immediately. We had to set it to not use any compatibility mode, but we did have to set Run this program as an adminisrtator, and had that applying for all users.
I have a question regarding the execution order while shutting down/logoff Windows and the scripts shutdown/logoff in the GPEDIT.MSC.
When I shutdown/logoff will the scripts in the gpedit.msc be executed before Windows closes everything or is it the other way around, that Windows closes every other running process and then starts the script?
Thank you.
Logoff scripts are run in the security context of the user that is logging off. That is important to remember as their rights are limited accordingly. As a log off doesn't necessarily require a shutdown, the system is still up and running. More info: https://technet.microsoft.com/en-us/library/cc753583%28v=ws.11%29.aspx?f=255&MSPPError=-2147217396
Shutdown scripts run in the security context of LocalSystem. They still need the command shell or script host to be running to execute, so the operating system is still running. To find out exactly what processes are still running, you could try dumping a process list to a text file in a shutdown script. You can find a little more info here: https://technet.microsoft.com/en-us/library/cc770300%28v=ws.11%29.aspx?f=255&MSPPError=-2147217396
Hope this helps.
After a few tests I found the answer.
Windows first closes all running applications and then starts the scripts in the GPEDIT.MSC.
I have a very specific problem that I need fixing. The major issue is that I don't exactly know how to properly search the remnants of my problem on google. Therefore I am coming to StackOverflow for advice in hopes that someone will assist me.
Summary
So I am writing an application which is to be PCI-compliant for the company which I am starting. The application involves IPC (Inter-process communication) and two "watch-dog" apps which monitor the status of the main application. One of these "watch-dog" applications is an updater (sends an HTTP Request to the server looking for updates of the application).
So! This method which I am using to check the server if the application is up-to-date is using the WinInet library and InternetOpen() to send the request. Then read the response of the page and use GetCookie() to store the response in a buffer. It shall then parse the response accordingly.
If the response says that the current version of my application is less than the version located on the server. It will then tell the customer (user) that their application is out of date, and ask them whether or not they want to update the software. If they choose to update the software, it will perform a Download And Execute from the internet and launch the update-installer on the user's PC.
The Problem
Unfortunately, windows is very "secure" when it comes to having an "unauthorized" application send an HTTP Request to an outgoing url, let alone download something from the server then execute it on the users PC.
My conclusion to this issue was to add the watch-dog programs to the Task Scheduler. That way after the main application is run, it will spawn the watch-dog programs and check if they are running with NTAUTHORITY privileges (which are granted by the Task Scheduler).
After implementing the code to create the task and point it to the location of the watch-dog programs, naming it, writing a description and everything. I executed the program. It ran without errors though here the REAL PROBLEM:
1) Programs executes
2) Spawns watch-dog programs
3) Watchdog program checks for new version
4) Version is found
5) Installer is downloaded, execute ... but
6) The installer does not appear on the screen!
When I run my 'Process Hacker' application to monitor all process actions. I can see that the new installer is download & executed. It is running as NTAUTHORITY/SYSTEM just like the watch-dog programs but it doesn't appear on the system.
I made sure that in my code the status of the window is set to SW_SHOWNORMAL not SW_HIDE. I also made sure that all flags are set accordingly. Though it doesn't appear on the screen!
When I run the application without adding it to the Task Scheduler as my user without NTAUTHORITY/SYSTEM status and just regular user status. It executes (obviously since I am already running as administrator) -- everything works fine. But after adding it to Task Scheduler and having it run with SYSTEM level privileges. The window doesn't appear on the screen visually. Why's that?
I would greatly appreciate anyone that is able to assist me with this problem. Thank-you!
edit 1
Can anyone help me understand how this user applied his fix in the registry? By reading the problem I can somewhat interpret that he had the same issue as me.
App is invisible if started from Task Scheduler without any user logged in
In any case, I am trying to use the advice that Gisley gave me to run the application in Interactive Mode. Possibly going to try to give that a try. Still looking for more answers but I am going to be working no this none-the-less in the meantime.
edit 2
I tried setting the INTERACTIVE FLAG and it had no effect unfortunately.
Allow me to just emphasize my problem:
For example I write a program which has message boxes and put it in a loop.
for
message box
get current pid
make process in the task scheduler
spawn new process as the task scheduler proc with NTAUTHORITY/SYSTEM
kill last proc pid
end for
Then when I execute it:
I get the message box. Then after new process opens with NTAUTHORITY/SYSTEM the message box does not appear anymore.
Same for if I open a calculator for example.
System("cmd.exe start /c calc.exe")
Program runs... opens calculator
Program gets NTAUTHORITY/SYSTEM status
ON the next loop it executes the calc.exe
I see it in my task manager but it doesnt appear on the screen
I hope the above helped emphasize the core of my issue. I dont see the processes opened by the task scheduler process id with NTAUTHORITY/SYSTEM rights... I dont see the procs executed by it on my screen, though I see them in the task manager | process hacker and they are running with NTAUTHORITY/SYSTEM privileges too.
A shot in the dark - try running the task in interactive mode, but you'll need to have a user logged on.
https://superuser.com/questions/616206/run-interactive-task-even-if-user-is-not-logged-on-windows
Alternatively, or additionally, pass parameters to the installer so that it installs silently.
Silent installation of a MSI package
We have some Batch scripts (.bat) in Windows to execute the “backups” and “archive log” for the databases. These scripts are called from Tivoli periodically.
For each executed script, the process creates a sub session in order to load the DB2cmd environment, in order to execute the db2 commands and exit.
daily.bat
call db2cmd hourly.cmd
The content of the script is this:
db2_job_saveddaily.cmd
db2 -fE:\DB2\scripts\tmp\db2_job_savedbhourly.db2 -zE:\DB2\scripts\tmp\db2_job_savedbhourly.log
exit
The content of the db2 file is (however, it is not important because it is executed correctly)
db2_job_saveddaily.db2
archive log for database ICMNLSDB
We are facing a problem with these scripts, and I think it is related with the exit. At one execution, the script freezes, and it starts to consume the whole CPU (see attached image). After this behavior, we cannot execute any other DB2 command from the CLP.
We kill all the CMD.exe and db2bp.exe processes, but the error persists.
There is nothing in the db2diag.log file, and the only solution is to restart the machine.
Probably, the CMD.exe process losses the communication with the db2bp.exe, and the exit cannot be executed. I would like to understand the origin of this problem and learn how to execute db2 processes in Windows.
Our friend #AngocA seems to check into SO often but hasn't been checking this dangling question even though he did something to close it. Let's at least put his answer in here so folk know it's CLOSED by user. :) Courtesy of tonight's Point Pimp. :-D
"The problem was in another db2cmd session where there was an
infinitive loop. This created a scenario when new db2cmd session
blocked because the first session used the whole CPU. – AngocA"