Unable to print PDFs or office documents via Scheduled task - powershell

I have a scheduled task set to run on a machine overnight. This task will iterate through a folder printing all the files found therein. I can run the process without issue while logged in however it does not print when run via the scheduled task.
More Info:
The scheduled task executes a powershell script that performs multiple functions such as generating and emailing reports, copying files across network folders and finally printing the contents of a folder. All of these tasks are performed without error if the executing account is currently logged in. If the account is not logged in and run via a scheduled task everything except the printing of Office and PDF documents works correctly (Text documents print fine).
Here is the function I am using to print the documents.
Function Print-File($file)
{
begin
{
function internal-printfile($thefile)
{
if ($thefile -is [string])
{
$filename = $thefile
}
else
{
if ($thefile.FullName -is [string] )
{
$filename = $thefile.FullName
}
}
$start = new-object System.Diagnostics.ProcessStartInfo $filename
$start.Verb = "print"
[System.Diagnostics.Process]::Start($start)
}
if ($file -ne $null)
{
$filespecified = $true;
internal-printfile $file
}
}
process
{
if (!$filespecified)
{
$test = write-Host process ; internal-printfile $_
}
}
}
When running from a scheduled task I can see the process start (Winword or AcroRd32) as I am dumping output to a text file however I do not see anything print. One other difference I noticed is that when I use this function while logged in the Applications other than Adobe reader (Office Apps) start to print the document then close. However when run from a scheduled task the applications do not close on their own.
I would appreciate any feedback, suggestions or pointers at this time as I have hit a wall as far as knowing what else I can check. I would also take suggestions as to an alternative way to accomplish the printing of the files. (NOTE: I cannot predict the file type in the folder)
NOTE: These symptoms are present on two machines, Windows server 2008 and Windows 7, both running Office 2007 and Adobe Reader 10.1.7

I'm trying to do the same thing that you are attempting. I'm pretty sure what you're running into is session 0 isolation. You can read more about it at this MSDN site and this Windows blog post.
I haven't tried the suggestions in the following answer to another question on SO, but it might be worth a try.
Creating Desktop-Folders for session 0
Here is another guy who is trying to print without having a user logged into the machine. There is an answer from someone who claims to know how to do what we're all trying to do, but he doesn't actually post the answer.

Too late for OP, but for future readers... I had the same problem, but with a windows shell .bat file, not PowerShell. As a scheduled task, the script would launch AcroRd32.exe /t, but it wouldn't print anything. Then after a delay, Acrobat was stopped, and the file was moved to the "Printed" folder like everything was good. It printed fine standalone, just not as a scheduled task.
(Background: I'm running Windows 10 x86 on one older computer so that we can use our two bulletproof HP LaserJet 1000 printers. However, the program we used for this in Win 7, batchdocprint, is incompatible with Win 10 and the company is gone. Due to having to learn arcane syntax and workarounds, I've spent way more money in hours getting a few lines of code (below) working right than the program cost, but I couldn't find a suitable replacement. The programs that I found either printed incorrectly, or had options for only one printer.)
The problem for me did seem to be Session 0 isolation blocking GDI+. I went with the seemingly "spammy" suggestion of getting Foxit Reader. It worked, and like Acrobat, the reader is free. I just replaced the path to AcroRd32.exe with the path to FoxitReader.exe
I don't think this will ever be possible with Acrobat Reader. The CLI is not officially supported, so the likelihood of Adobe ever changing it to print without launching the GUI is minimal.
As far as other file types, it depends on what you're using to print them, and whether it can open and print without a GUI. I haven't decided whether to implement this for other common file types so that we can just drag-and-drop, or to keep forcing the users to use the Acrobat PDF printers that are set up to save PDFs in the hot folders. Right now, it's the latter.
My code, for reference, to hopefully save someone else my headache. I only changed/shortened names, and removed duplicate code for the second folder/printer. Note that taskkill requires administrative privileges. Also, you probably need to have a folder named "Printed" in your hot folder, since I don't check for its existence:
#ECHO OFF
REM Monitors folders for PDF's and prints.
REM Use PING for delay - no built-in sleep functionality.
REM Using START backgrounds the process so the script can move on.
:LOOP
cd C:\Hot Folder\
for %%a in ("*.pdf") do (
start "" "C:\Path\To\FoxitReader.exe" /t "C:\Hot Folder\%%a" "HP 1000"
ping 1.1.1.1 -n 2 -w 5000 >NUL
taskkill /IM FoxitReader.exe /F
move /Y "%%a" ".\Printed\%%a")
ping 1.1.1.1 -n 2 -w 5000 >NUL
goto LOOP

Not sure if you ever found the solution to this, but it happens that the printer to be used by task scheduler job should be registered under:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Printers (local printers)
vs
HKEY_Current_User\Printers\Connections (session printers)

Related

Trying to get a Powershell Script that will run in a 2nd window and monitor in real time other running scripts / report all Errors / ExitCodes

I am fairly new to writing code in Powershell. For my job I have to write multiple Powershell scripts to make changes in the Hardware and Software settings as well as the Registry and Group Policy Editor to get these applications to run. These applications are a little older. Upgrading these software applications or the hardware then run on is NOT an option. as an example, when Microsoft releases the new patches on like Patch Tuesday...when those patches are applied there is a high probability that something will be changed which is where I come in to write a script to fix the issue. I have multiple scripts that I run. When those scripts are ran they may end up terminating because of an Error Code or an Exit Code. A large part of the time I do not that the script has failed immediately.
I am trying to figure out a script that I can run in a 2nd PowerShell Console Window. I am thinking that the only purpose of this script is to just sit there on the screen and wait and monitor. Then when I execute a script or Application (the only file extensions that I am worried about are: EXE, BAT, CMD, PS1) if the script/application that I just ran ends with an exit code or an error code....then output that to the screen...in REAL TIME.
Below, I have a small piece of code that kind of works, but it is not what I am wanting.
I have researched online and read and read tons of stuff. But I just can't seem to find what I am looking for.
Could someone please help me with getting a script that will do what I am wanting.
Thank you for your help!!!!
$ExitErrorCode =
"C:\ThisFolder\ThatFolder\AnotherFolder\SomeApplication.EXE # (this
would
# either be an EXE or CMD or BAT or PS1)"
$proc = Start-Process $ExitErrorCode -PassThru
$handle = $proc.Handle # cache proc.Handle
$proc.WaitForExit();
if ($proc.ExitCode -ne 0) {
Write-Warning "$_ exited with status code $($proc.ExitCode)"
}
Possible duplicate of the approaches shown here:
Monitoring jobs in a PowerShell session from another PowerShell session
Monitoring jobs in a PowerShell session from another PowerShell session
PowerShell script to monitor a log and output progress to another
PowerShell script to monitor a log and output progress to another

Automating a command line exe with powershell

We have a very old tool that our company uses that runs some basic command line scripts to deploy some text files to our servers. It works well, but the process is repetitive.
When the exe runs it does 3 prompts...
"Enter The destination Folder"
"Enter The Server"
"Enter the Password"
We have to do this for about 10 servers, and its sitting there doing a lot of copy paste. Since this process was created everything has been standardized.
So I wanted to make a powershell script that ran the exe process and basically pasted the 3 pieces of information and just loop the server name..
I THOUGHT I had the process working using SendKeys... but even though it appeared to work in every way... it never ACTUALLY did anything. So im not sure if the exe did not like send keys or what.
So then I resolved to trying to use Send Keys outside of Windows forms and launch cmd.exe and run it that way.
That way seemed to work as well, but the results were the same, the files were never updated.
If I did this process manually in powerhsell they worked fine though.
My final attempt was doing this.
try {
$MyProcess = New-Object System.Diagnostics.Process
$MyProcess.StartInfo.FileName = "c:\MyProcess.exe"
$MyProcess.StartInfo.Arguments = "arguments for process"
$MyProcess.StartInfo.UseShellExecute = $false
$MyProcess.StartInfo.RedirectStandardInput = $true
$MyProcess.Start()
$StdIn = $MyProcess.StandardInput
$StdIn.WriteLine($destinationFolder)
$StdIn.WriteLine($server)
$StdIn.WriteLine($password)
} finally {
if($StdIn) {
$StdIn.Close()
}
This process DOES update the files, however I cannot loop it, because as soon as the first exe finishes the script crashes with the error
"Cannot Read Keys when Either application does not have a console or when a console inout has been redirected"
I am looking for a way to get this to work...

Task scheduler "Run whether user is logged on or not" issue to startup application

I have a .bat file that starts up a powershell script.
Within this powershell script, i startup PowerBI with a given database.
The powershell script waits till powerBI has been done starting up, and will then be exporting data to some datadump files.
Doing this manually works fine, and also when its on the task scheduler to run when user is logged on.
The moment i change this to "Run whether user is logged on or not" it doesnt work anymore.
The reason behind this, is that it seems that powershell is unable to start PowerBI and therefore there is no open data to query in the rest of the script.
So the positive side is it runs the bat and powershell just fine, only the powershell itself seems incapable to start powerBI.
Are there any solutions to this? should i for example use a different method to call the appliation to start?
currently the powershell snippit to start the app looks like this:
$PBIDesktop = "C:\Program Files\Microsoft Power BI Desktop\bin\PBIDesktop.exe"
$template = "C:\LiveData\Data.pbix"
$waitoPBD = 60
$app = START-PROCESS $PBIDesktop $template -PassThru
log_message "Waiting $($waitoPBD) seconds for PBI to launch"
Start-Sleep -s $waitoPBD
I faced similar issue. So, sharing my experience..
First of all, please verify couple of things.
Specify user account which will be used to invoke the job. Also, ensure that, the account have sufficient permission.
Don't forget to un-check the checkbox (as shown in screenshot) under Conditions Tab
Just found this one - sorry it took so long :D
But, i had this totally nervwrecking issue to.
Solution for me is to realize that the task scheduler is very deep part of the OS.
Thats why i have to grant access to the file, for the computername$ (system name) on the file or folder containing the file to run.
Rightclick on the file or folder -> Security. Select edit and add [Name of your computer]$ and give the read and execute permissions.
That's the only way I can make it run.
But i hope you found the solution in the meantime :)

Windows Scheduled task succeeds but returns result 0x1

I have a scheduled task on a Windows 2008 R2 server. The task includes a Start In directory entry. The task runs, and the batch file it runs does what it is supposed to do. When I run the batch file from a command prompt, I see no errors. The problem is that the "Last run result" is 0x1 (incorrect function call).
I did get this at one time with an incorrect DOS statement IF EXISTS file.txt DO (Copy file.txt file1.txt) that was corrected by dropping the DO statement. The current batch file does not show me any errors or warnings.
Why am I getting a 0x1 result?
Batch file that is run:
PUSHD \\JUKEBOX4\Archives\CallRecording
REM only move csv and wma together. wma should be created last.
IF NOT EXIST C:\CallRecording (MKDIR C:\CallRecording)
FOR /f %%f IN ('DIR /b *.wma') DO (
IF EXIST %%~nf.csv (MOVE /Y %%~nf.* C:\CallRecording\)
)
POPD
CD /D "C:\Program Files (x86)\Olim, LLC\Collybus DR Upload"
CollybusUpload.exe
POPD
Info on scheduled task setup:
Program to run: C:\Program Files (x86)\Olim, LLC\Collybus DR Upload\CallRecordingUploadFromH.cmd
Start in: C:\Program Files (x86)\Olim, LLC\Collybus DR Upload
Run whether user is logged on or not, highest privileges.
History screen, task completed entry
"Task Scheduler successfully completed task "\Call recording upload to portal from NH" , instance "{1449ad42-2210-427a-bd69-2c15e35340e6}" , action "C:\Windows\SYSTEM32\cmd.exe" with return code 1."
First screen of Task Scheduler shows "Run Result" of "Success"
It seems many users are having issues with this. Here are some fixes:
Right click on your task > "Properties" > "Actions" > "Edit" |
Put ONLY the file name under 'Program/Script', no quotes and ONLY the directory under 'Start in' as described, again no quotes.
Right click on your task > "Properties" > "General"
| Test with any/all of the following:
"Run with highest privileges" (test both options)
"Run wheter user is logged on or not" (test both options)
Check that "Configure for" is set to your machine's OS version
Make sure the user account running the program has the right permissions
I found that I have ticked "Run whether user is logged on or not" and it returns a silent failure.
When I changed tick "Run only when user is logged on" instead it works for me.
I've had the same problem. It is just a batch-file, working when manually started, but not working as a scheduled task.
there were drive-letters in the batch-file like this:
put z:\folder\file.ext
seems like you should not use drive-letters, they are bound to the user, who created them - for me this little change made it work again:
put \\server\folder\file.ext
For Powershell scripts
I have seen this problem multiple times while scheduling Powershell scripts with parameters on multiple Windows servers.
The solution has always been to use the -File parameter:
Under "Actions" --> "Program / Script" Type: "Powershell"
Under "Add arguments", instead of just typeing "C:/script/test.ps1" use -File "C:/script/test.ps1"
Happy scheduling!
Windows Task scheduler (Windows server 2008r2)
Same error for me (last run result: 0x1)
Tabs
Action: remove quotes/double-quotes in
program/script
and
start in
even if there is spaces in the path name...
General:
Run with highest privileges
and
configure for your OS...
Now it work!
last run result: The operation completed successfully
Probably not the cause of the OP's problem; for me the problem was caused by the fact that my program called a SQL function, and the service account the windows task was set up with did not have the required SQL permissions. That also gives a 0x1
This answer was originally edited into the question by the asker.
The problem was that the batch file WAS throwing a silent error. The final POPD was doing no work and was incorrectly called with no opening PUSHD.
Broken code:
CD /D "C:\Program Files (x86)\Olim, LLC\Collybus DR Upload" CALL CollybusUpload.exe POPD
Correct code:
PUSHD "C:\Program Files (x86)\Olim, LLC\Collybus DR Upload" CALL CollybusUpload.exe POPD
In my case it was an encoding issue. We wanted to start en existing batch file, and it resulted in "return code 1", and the desired action wasn't performed. I've accidentally found that the batch file was shown in Notepad as one with UTF-8 encoding (actually without any reason, as we have no special characters in the text). I saved it as ANSI, and it solved the problem for us. Might be, that it was a kind of encoding corruption in the file that prohibited Task Scheduler and cmd.exe to open the file, although it was displayed correctly in Notepad.
On our servers it was a problem with the system path. After upgrading PHP runtime (using installation directory whose name includes version number) and updating the path in system variable PATH we were getting status 0x1. System restart corrected the issue. Restarting Task Manager service might have done it, too.
I was running a PowerShell script into the task scheduller but i forgot to enable the execution-policy to unrestricted, in an elevated PowerShell console:
Set-ExecutionPolicy Unrestricted
After that, the error disappeared (0x1).
Just had the same problem here. In my case, the bat files had space " "
After getting rid of spaces from filename and change into underscore, bat file worked
sample before it wont start
"x:\Update & pull.bat"
after rename
"x:\Update_and_pull.bat"
For me the problem was the PowerShell script being ran had #Requires -RunAsAdministrator at the top, meaning it needs to run in an elevated command prompt as an Admin, but the user the Scheduled Task was set to run as wasn't an admin on the local computer. So even though Run with highest privileges was checked in the scheduled task, I still had to make the user an Administrator on the computer. Once I did that, the script ran as expected.
Since there is always more than one reason this could happen I thought I'd share some troubleshooting tips that helped me diagnose my issue.
Always adding a "start in" parameter first since thats an easy fix, even just adding the drive letter can help, e.g. C:\
If you're running "whether user is logged on or not" and it is failing it might be an issue with your user and/or user environment.
Switch the task to run only when user is logged in temporarily for
troubleshooting purposes.
Make sure you're actually logged in AS the user you're telling the task
to run as. (PATH and other environment variables are different by user
and if you see the task running on one user successfully that doesn't
necessarily mean it will run successfully for another user even if they're in the same security group.)
Add pauses or some other type of debugging to your script to give you
time to see any errors that may pop up.
Perform a manual run from the task scheduler window.
Fix any errors you see from your debugging statements. Rinse and repeat.
If it runs successfully switch back to run "whether user is logged on
or not" and try another manual run. If it works now you're all set.
If nothing has helped so far you might need to dig in deeper to your user and file privileges. My troubleshooting tips assume that you have been able to get a past task running using a specific user login already. They don't cover building a scheduled task from a fresh install necessarily. Luckily I haven't had to do that.
What solved it for me was that I was using a local administrator account instead of the domain account so I changed the "Run as" to the domain account.
It turns out that a FTP download call using winscp as last thing to do in the batch caused the problem. After inserting the echo command it works fine. Guess the problems source could be the winscp.exe which do not correctly report the end of the current task to the OS.
del "C:\_ftpcrawler\Account Export.csv" /S /Q
"C:\Program Files (x86)\WinSCP\WinSCP.exe" /console /script="C:\_isource\scripte\data.txt"
echo Download ausgeführt am %date%%time% >> C:\_isource\scripte\data.log

Checking Time and executing different instrcutions based on hour

I am using a Robocopy command on a Windows Server 2003 server to copy a series of EDB files to special folders from user workstations onto a server. I want to run the robocopy commands twice, once in the mid-morning and once in the afternoon.
The way I KNOW how to do this would be to write two independent batch files that are scheduled to run at different times. Each batch would copy the EDBs to different directories.
But it occurred to me I should be able to do this in one batch file by:
Check the current time.
Note whether it's before 1200pm or after 1200pm.
If it's before 1200pm, run this set of Robocopy commands.
If it's after 1200pm, run the other set of Robocopy commands.
I am going to implement this the way I know how to do it, with the two batch files. I'd like to learn how to do it in other ways. I am open to doing this in any way -- Powershell, Python, etc. Admittedly, I am leery of installing anything on this production server that I wouldn't normally have to install. For instance, I could install Python, but it would be for this job only and that seems a little like overkill. (Feel free to disabuse me!)
There are probably several way to do what you are asking. The first part, running different codes depending on the time of day is pretty straight forward. Just use this:
if ( (Get-Date -UFormat %p) -eq "AM" ) {
<Code if doing before noon>
} #End if
else {
<code if doing after noon>
} #end else
You can run robocopy commands in Powershell without any fancy tricks. Here is a link to a question about robocopy.
As far as scheduling the task, this link will show you how to schedule the powershell script with the task scheduler.
To get anything else, your going to have to do some trial and error, then come back with failures or roadblocks to get more help.
Another possibility:
Switch ((get-date).tostring('tt'))
{
'AM' {'Morning script'}
'PM' {'Afternoon script'}
}
You could use something like this
set t=%time:0,2%
if %t% lss 12 (
REM First set of robocopy commands here
) else (
REM Second set of robocopy commands here
)