Windows Task Scheduler Powershell get URL and download file - powershell

I am struggling with automating download of a file from website that opens a new tab when download is triggered and closes it right before the prompt to Save/Open/Close comes up in the main window. The script itself works just fine when launched manually until I try it in Task Scheduler. It runs great until it snags on the download. I've included a code to capture the URL of the file that needs to be downloaded and then pass it to Invoke-WebRequest which works fine out of PowerShell ISE but doesn't return any results when launched from Task Scheduler. I've included the counter and test file creation into the code to see if contents of do-while execute at all, and all 10 attempts were recorded. It's the part that searches through active URLs that's not returning results when launched via Task Scheduler.
# >> Keep trying to capture the CSV download link
$i = 1
Do {
$i | Add-Content -Path "C:\userfolder\try.txt"
$urls = (New-Object -ComObject Shell.Application).Windows() |
Where-Object {$_.LocationUrl -like "https://sitename.com/ReportViewer*"} |
Where-Object {$_.LocationUrl}
$reportURL = #($urls)[0].LocationURL
$i ++
}
While ($reportURL -eq $NULL -and $i -le 10)
# >> Send download link to web request and save to file
Invoke-WebRequest -Uri $reportURL -OutFile "C:\userfolder\ProfileList.csv"
I have tried the Wscript.Shell AppActivate and SendKeys('%S') before but the AppActivate wouldn't work probably because the PowerShell console window was hijakcing focus when launched via Task Scheduler. The task is set to execute powershell.exe with Arguments: C:\userfolder\CPdownload.ps1 -RunType $true, - and Start in: C:\userfolder. Run: only when user is logged in and with highest privileges; configured for Windows Server 2012 R2.
I've also tried launching the shell script through batch file from Task Scheduler with exactly the same result.
Thanks in advance for any pointers.

Probably your task needs to be run in interactive mode. By default scheduled tasks are run in Session 0. You can schedule task for interactive mode with /IT parameter. Check the following link for more info
https://msdn.microsoft.com/en-us/library/bb736357(VS.85).aspx

Old post however besides changing the script to interactive mode (this fixes it) you can change the Powershell execution policy to unrestricted (Set-ExecutionPolicy -ExecutionPolicy Unrestricted) if you wish to run the script outside of interactive mode. Just thought I'd post as recently come across this myself.

Related

Run command on powershell launch using pwd variable

When you're in file explorer you can click on File > Open Windows Powershell(or its icon in the Quick Access Toolbar) to start an instance of Powershell in the directory that your file explorer is in. I would like to then automatically run a simple command in this directory and close the Powershell window after it is done.
I have tried adding my command to my Powershell Profile but it executes before the path variable has been set and it runs with $pwd being equal to C:\Users\MyUsername (my home directory) or C:\WINDOWS\system32 (seems to be a race condition of some sort, no idea why it does one or the other). To the best of my understanding this is because the file explorer "open in powershell button" opens powershell and THEN cd's to the directory I was in in file explorer. So when the profile.ps1 is ran it is using the only directories it knows if since the cd call hasn't been made yet. This is similar to running the command start powershell.exe in cmd vs start powershell.exe -command "cd 'C:\wherever'". The former correctly runs my profile command while the latter uses the current directory of cmd and not the C:\wherever.
So, obviously the $pwd variable is being assigned at different times in the case of opening it from cmd and opening it from file explorer. Is there some way to delay the execution of a command in the profile until after the shell has fully loaded? Simply sleeping the script doesn't help.
Alternatively, if anyone knows how to edit the registry so that I can change the behavior of clicking File > Open Windows Powershell (since it must have access to some variable storing the current directory and I assume it calls the Powershell executable with this variable as an argument being cd'd to), that would work too.
Then again I could be incredibly naive about how File > Open Windows Powershell and the Powershell instantiation process works.
Any help is greatly appreciated, thank you!
I figured it out in the most hacky, gross way ever, but without easy access to Windows internals this is the only working method I could find. I set up my powershell profile to make my window title my prompt like so:
function Prompt
{
$host.ui.RawUI.WindowTitle = $(get-location)
“PS> “
}
Then I set up a task in the Task Scheduler that was triggered by powershell reaching its prompt (there are 3 possible hooks, when the console is starting up, when it starts an IPC listening thread, and when the console is ready for input). I used the Event Viewer to do this (I was going to post screenshots but I don't have 10 reputation yet).
Then, I set the action on this task to run the script shown below, which reads from the window title of my first instance of powershell
Start-Sleep -s 1
$A = Get-Process -Name powershell | Where-Object -FilterScript {$_.Id -ne $PID}
$B = $A.MainWindowTitle
& C:\Program` Files\MyProgram\MyProgram.exe "$B"
stop-process -Id $A.Id
stop-process -Id $PID
This whole menagerie of events properly runs my program with the current file explorer directory as an argument (and then closes powershell) when I click the little powershell icon on the quick access toolbar in file explorer.
Found a much cleaner and faster way to do this. All I had to do was set up my profile to look like this, no tasks or second instance of powershell required
function Prompt
{
& C:\Program` Files\MyProgram\MyProgram.exe "$pwd"
stop-process -Id $PID
}

Powershell PSEXEC not working via Control-M

PS Version: 2.0
Hi All,
I am trying to run the batch file from a powershell script using psexec.
The script runs fine while triggering manually or using windows task scheduler; however, powershell get triggered from Control-m but do not complete the part where psexec is used. The rest part of powershell script runs fine.
Below is the function which is not working, besides it do not give any error, it just freezes the script:
function Archive_Logs($Server_Name,$Tool_Path,$Name)
{
foreach($TPath in $Tool_Path){
C:\Windows\System32\PsExec.exe \\$Server_Name "$TPath\ziplogs.bat"
if($LastExitCode -eq 0)
{
"$Name Server logs archive Started successfully at $(Get-Date)" | Out-File $LOGFILE -Append
}
}
}
The account used by Control-M is local admin on the servers.
How are you calling the Powershell? When you create a .bat file and invoke it from there it fixes a lot of issues, e.g, bat file contains 1 line -
powershell -command "& C:\MyPSscripts\archiver.ps1"
See -
https://communities.bmc.com/thread/117415

Local Powershell script to trigger VBS script inside Citrix instance

I am trying to get a local powershell script to trigger a VBS script inside a citrix instance. The events should be this:
Citrix Instance opening Windows Explorer ----> Network Path of script typed into the windows explorer session
I'm using the WfIcaLib.dll (ICOSDK) that came with the Citrix receiver install. Documentation PDF for the Citrix ICOSDK is available here
So this is the code I'm using, which works PERFECTLY in Powershell command line, but when I use the 32-bit ISE, it does nothing other than telling me the DLL has been loaded. I get no errors, but the Citrix Client never actually opens like it does when I run the same exact commands through Powershell command line.
#load Citrix ICA Client SDK
[System.Reflection.Assembly]::LoadFile("C:\Program Files (x86)\Citrix\ICA Client\WfIcaLib.dll")
$ICA = New-Object WFICALib.ICAClientClass
$ICA.Address = "***.***.***.***:****"
$ICA.Application = "Windows ExplorerFED6"
$ICA.Username = "******"
$ICA.Domain = "**"
$ICA.Launch = $true
$ICA.Outputmode = [WfIcaLib.OutputMode]::OutputModeNormal
$ICA.SetProp("Password", "*********")
$ICA.TWIMode=$true
$ICA.Connect()
Any ideas?
EDIT: SOLVED - after reopening under 32-bit ISE and getting code to work, I could not run the .ps1 file since it kept defaulting to 64-bit (even if using Open With on 32-bit powershell version). Running the script via command prompt or 32-bit powershell console both worked.
Using any method suggested by Mike Garuccio worked just fine. I will most likely end up using a Task Scheduler to run the script.
It looks like the problem is a versioning one, which you can deal with using start-job (was originally going to do this with a runspace but that's a lot more code for no real benefit). This will start a job to run your code under 32-bit powershell, it should still place any GUI elements or popups on screen but if you need to get any data out from the script later you'll need to receive the job. code would look something like below.
$SB = {
[System.Reflection.Assembly]::LoadFile("C:\Program Files (x86)\Citrix\ICA Client\WfIcaLib.dll")
$ICA = New-Object WFICALib.ICAClientClass
$ICA.Address = "***.***.***.***:****"
$ICA.Application = "Windows ExplorerFED6"
$ICA.Username = "******"
$ICA.Domain = "**"
$ICA.Launch = $true
$ICA.Outputmode = [WfIcaLib.OutputMode]::OutputModeNormal
$ICA.SetProp("Password", "*********")
$ICA.TWIMode=$true
$ICA.Connect()
}
Start-Job -ScriptBlock $SB -RunAs32
get-job | Receive-Job
Alternatively, you could also use a simple .bat file as a launcher with something like C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -file yourscript.ps1
or if you need everything to be wrapped in powershell and the job does not work you can use the solution Here that basically does the same thing but from within powershell (drop the if statement they use tho, just use the stuff contained inside it like below, with any changes you need to make wrt the profile and interactive settings.)
&"$env:windir\syswow64\windowspowershell\v1.0\powershell.exe" -noninteractive -noprofile -file "C:\Path o\script.ps1" -executionpolicy bypass
hope one of those works for you!

Powershell script run from task scheduler unable to open word document

I am trying to use a powershell script to get the wordcount from a number of word files and then output that to a csv file. This works as expected when run from the powershell prompt, and works when called from the cmd prompt directly or from inside a perl script, however the script fails to work when called as a scheduled task.
This is not an ExecutionPolicy issue causing the script to not run at all. The script is running and produces some output, but when launched from task scheduler it is unable to open any word documents.
The relevant powershell code is below:
$folderpath = "C:\some\where\*"
$fileTypes = "*.docx"
$word = New-Object -ComObject word.application
$word.visible = $false
Get-ChildItem -path $folderpath -recurse -include $fileTypes |
foreach-object `
{
$path = ($_.fullname).substring(0,($_.FullName).lastindexOf("."))
try {
$doc = $word.documents.open($_.fullname, $confirmConversion, $readOnly, $addToRecent, $passwordDocument)
} catch {
"FROM CATCH UNABLE TO OPEN $($_.fullname)" >> $wordCountFile
}
if($doc) {
$wordCount = $doc.ComputeStatistics("wdStatisticWords")
"$($_.name), $wordCount" >> $wordCountFile
$doc.close([ref]$false)
} else {
"UNABLE TO OPEN $($_.fullname)" >> $wordCountFile
}
} #end Foreach-Object
$word.Quit()
(Note that alternative methods people cite for getting the word count from word documents do not actually return the correct count as this method does when it works.)
When run as a scheduled task (set to run with highest privileges and as an administrator user) using:
cmd /c start PowerShell.exe -NoLogo -NonInteractive -ExecutionPolicy Bypass -File "C:\path\to\script\CountsInWords.ps1"
or when run with a similar command from a perl script launched by a scheduled task (my normal use case) and in both cases the task is set to run with highest privileges the powershell script does not work correctly.
The catch block is apparently never reached, as the print statement never makes it to the file, however the $doc is always null.
Additionally, when started as a task the script leaves a word process open and using a 100% cpu for 1 thread which will eventually cripple my machine.
To summarise:
run script as human (no matter how many levels of indirection) -> works perfectly
run script from task (as administrator user) -> script runs but cannot access word documents, also unable to stop word process despite always hitting the $word.Quit line.
EDIT: With #TheMadTechnician's advice about office first time startup for a new user requiring some details: On further inspection, looking at the processes in task manager, I don't see the word processes unless I click on "show processes from all users", but then they show up, but have the user listed as me. How can a process be both explicitly listed as me, but count as another user?
Attempting to set $word.visible = $true in the script didn't actually make anything appear when launched from task scheduler, so I don't know either how to verify that it is waiting for input, or how to give it that input as the correct user to make it go away...
You may be able to follow the solution named at the question How to run a Windows 2008 task from the scheduler with "interact with desktop".
Summary: If you have 64-bit Windows: Create %SystemRoot%\SysWOW64\config\systemprofile\Desktop. If you have 32-bit Windows, create %SystemRoot%\system32\config\systemprofile\Desktop.

Powershell scripts manipulating desktop elements don't work with Scheduler

I have 2 scripts working, when I start them manually.
Moving mouse cursor out of Screen:
[system.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | out-null
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point(1999,100)
If there is a chrome browser open with title HUD, put it to kiosk mode:
[void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
[Microsoft.VisualBasic.Interaction]::AppActivate("Hud - Google Chrome")
[void] [System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")
[System.Windows.Forms.SendKeys]::SendWait("{F11}")
If I put them in a Scheduled Task on Windows 7 they don't work.
They work if I start a batch file calling the script file
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noninteractive -command "&C:\Users\Miniuser\Documents\chromeHUD.ps1"
But not if I start the batch file in a Scheduled Task.
It seems in a Scheduled Task I can't acces my UI elements.
Any ideas?
When the script runs as a scheduled task, it runs in a different context/session and there is no GUI that it can "see", nor any way to interact with your existing session.
As alroc answers, it does run under another context/session.
I was not able to find any workaround to get pass this... Using pure powershell... However i was able to get the job done with wscript.
in your PS script, open your chrome with this
(new-object -com wscript.shell).run("http://localhost/",3)
It will open the default browser in full screen. i could use this with sendkeys in the task scheduler!
To run a script as a scheduled task that must interact with the desktop
You have to create a folder (or two on a 64bit-windows):
(32Bit, always) C:\Windows\System32\config\systemprofile\Desktop
(64Bit) C:\Windows\SysWOW64\config\systemprofile\Desktop