I have been working on a single image WDS deployment for our company laptops for a few months as a sort of unsanctioned side project. I finally made a breakthrough a month ago and I got the image working for just about every model laptop we have, except for the Dell Latitude E5430. After applying the image the system would reboot to do the OOBE install. After showing the windows loading screen and before it would normally start the rest of the install, the system would BSoD and reboot.
I was unable to boot into any form safe mode and boot logging and debug mode were useless because the BSoD was occurring before either of those become useful. While booting into safe mode, the last line displayed was the disk driver. I was only able to see the blue screen info after choosing the Disable the Automatic Restart on System Failure in the advanced boot options. (BTW, kudos to Microsoft for not making it possible to set that as a permanent boot option in an offline state, really great idea guys :( ) I assumed this storage drivers were the cause and I already knew that some of our laptops require us to switch the SATA mode in the BIOS if we weer to swap hard drives between models. However, doing so did nothing to alleviate the BSoD.
I tried many things, but ultimately I resorted to disabling all hardware in the BIOS and this got the machine to boot up without a blue screen. The next step was to re-enable everything and then disable one thing at a time. Ultimately, disabling USB was what would allow the machine to boot. So it is apparently a USB driver issue. I booted into Win PE and use DISM to investigate the USB drivers. I didn't see anything unusual, but decided to remove all of the USB hub drivers. The system would then boot BSoD free without USB disabled, however, with no USB hub driver, USB didn't work. After installing the USB drivers from the E5430 driver cab, it worked fine, but to my surprise, it just reinstalled the same USB hub driver I had removed offline. What?
I take a look at the driver stores on the WDS server and, sure enough, it is the same driver file and version I had just installed. Obviously it would be since I imported the drivers to WDS from the exact same driver cab. I decided to take a look at the install image and see what drivers were installed in it. Turns out the install image contained a newer version of the same USB hub driver. I had used a Dell Latitude E5450 to create my base image, so the E5450 drivers are native to the install image. I removed all the USB hub drivers from the install image and set to re-imaging an E5430. This time around there was no blue screen on first boot. USB also worked properly after windows was finally up and running.
Though I don't see it documented anywhere, apparently the newer USB hub driver is not backwards compatible with the older firmware. And, for whatever reason, the OS was choosing the wrong USB hub driver at boot even though the correct one gets chosen during install due to the fact that the newer driver is in the install image.
IT Trial and Error
IT Trial and Error captures the trials and tribulations of IT related work. Included are fixes, frustrations, and fascinations related to the fields of IT, Systems Administration, Web Hosting, Visualization, Programming, and Systems Engineering. The goal is to provide both real world fixes to IT problems, insight to the thought process behind them, and commentary on these subjects.
Thursday, April 23, 2015
Monday, November 24, 2014
Automatically Print and Delete PDFs Dumped in a Folder
Problem:
Last week I spent an inordinate amount of time setting up a new network scanner. One of the features this scanner lacks is the ability to scan directly to a printer emulating a copier. The scanner operates under the assumption that you have network printers with FTP print capabilities than can natively print PDFs. Unfortunately, the printers we have do not support native PDF printer, though they do support FTP printing of driver generated .prn files.
"No biggy!" I thought. "Surely others out there have run into this and there are some ready made PowerShell or VBS scripts to do this." I was wrong. What I didn't consider is that PDFs need to be processed by a PDF reader application to then be sent to a printer driver and subsequently printed. I did find scripts that would do this with Adobe Reader, but it would only work to the default printer. This wouldn't work for us as we need to differentiate between the color printer and black and white printer.
In summary: windows cannot natively print PDFs via script and a third party PDF viewer will be needed.
After some digging I found Sumatra PDF. It is a free, open source PDF viewer that has some command line print options that do not launch the GUI. The key difference between this PDF viewer and others I researched was the ability to specify a printer from the command line. So long as the printer has been added to the machine Sumatra PDF is launched on, that printer can be used to print PDFs from the command line without launching the GUI along with error suppression. This makes it the ideal candidate for scriptable PDF printing.
After selecting the PDF viewer to be used, I just needed to create the surrounding script to scan a folder for PDFs, execute Sumatra PDF to print the PDF, and then delete the PDF file. Then I added a new scan to network option to the scanner and have it save the scan to the shared folder. I created multiple "dump" folders, shared them, created multiple scan to network options to accommodate multiple printers, and concurrently ran multiple instances of the PowerShell script. I then had a functioning copier emulation.
There are a few caveats. The first of which is that this only works for single-sided printing and not duplex printing. If you scan a double sided-document, it will only print single-sided. To correct this, I could modify the script to accept more Sumatra PDF command line arguments to enable double sided printer, create another dump folder, create another scan to network settings, and set the script to monitor that folder, and then print using the double-sided option. I decided that wasn't completely necessary for our environment, but it's not to hard to implement.
The next caveat is that this has to run as a task that starts on machine startup. PowerShell windows tasks are a pain. I will give an example task after the script code to use as reference. This also means the task needs to run as a user that has read/write to the "dump" folders, execute permissions on Sumatra PDF, and print permissions. I gave up trying to make this all work nicely and have the task running with elevated privileges. You could by pass all this and just run the scripts in a perpetually open PowerShell window, but that's not a very "survivable" option.
The final caveat is the delay. This is more of a user experience issue than anything else. A copier would scan and start printing right away. This setup needs to scan, upload, get processed, send to printer, print. This is good enough for government work, but probably best to get something that does direct copying if your users are impatient. The script does include an adjustable sleep cycle setting allowing you to scan the folder more or less frequently. But the lower the sleep seconds, the more file system reads you will inflict on whatever system houses the "dump" folders.
Now, I will shut up and give you what you googled for.
Code:
######## Configuration ###########################
# Parameters:
# DUMPFLDR: location of the dump folder where pdf's will be deposited
# PRINTER: Printer share location
# SUMATRA: Location of the sumatrapdf.exe (A free PDF viewer used to print the PDFs)
# http://blog.kowalczyk.info/software/sumatrapdf/download-free-pdf-viewer.html
# SLEEPFOR: How long to sleep, if necesary, between program loops in seconds
#
# Example:
# pdfdump.ps1 -DUMPFLDR "C:\scripts\pdfdump" -PRINTER "\\printserver\PRINTER1" -SUMATRA "C:\scripts\SumatraPDF.exe -SLEEPFOR 15 -LOGFILE "c:\script\pdfdump.log"
#
# The defaults can be set below for when no command line parameter is given
param(
[string]$DUMPFLDR="D:\PDFDUMP\PRINTER1",
[string]$PRINTER="\\printserver\PRINTER1",
[string]$SUMATRA="C:\scripts\SumatraPDF.exe",
[int]$SLEEPFOR=15,
[string]$LOGFILE="c:\scripts\pdfdump.log"
)
####### End configuration ########################
$scriptpath = $MyInvocation.MyCommand.Path
$hostname=hostname
$ErrorActionPreference="SilentlyContinue"
echo "$(get-date) - Starting pdfdump from $scriptpath on $hostname with parameters DUMPFLDR:$DUMPFLDR PRINTER:$PRINTER SUMATRA:$SUMATRA SLEEPFOR:$SLEEPFOR LOGFILE:$LOGFILE" | Out-File -Append $LOGFILE
while ( $true )
{
$starttime = $(get-date)
get-childitem -recurse -path $DUMPFLDR -filter "*.pdf" | % {
$curfile = $_
echo "$(get-date) - Printing $DUMPFLDR\$curfile on $PRINTER..." | Out-File -Append $LOGFILE
& $SUMATRA -silent -print-to $PRINTER $DUMPFLDR\$curfile | Out-Null | Out-File -Append $LOGFILE
echo "$(get-date) - Deleting $DUMPFLDR\$curfile..." | Out-File -Append $LOGFILE
Remove-Item $DUMPFLDR\$curfile | Out-File -Append $LOGFILE
}
$elapsedtime = $(get-date) - $starttime
$sleeptime = $SLEEPFOR - $elapsedtime.seconds
start-sleep $sleeptime | Out-File -Append $LOGFILE
}
Scheduled Task Configuration Example:
This assumes the following:- Script location: c:\scripts\pdfdump.ps1
- Network printer: \\printserver\PRINTER1
- Dump folder: d:\PDFDUMP\PRINTER1\
- Log File: C:\scripts\pdfdump.log
- General Tab
- Name: PRINTER1 PDF Dump
- Security Options
- Run whether user is logged on or not
- Run with highest privileges
- Triggers Tab
- At Startup
- Action
- Action: Start a program
- Program/script: PowerShell
- Add arguments: -NonInteractive -WindowStyle Hidden -command "& C:\scripts\pdfdump.ps1 -DUMPFLDR 'D:\PDFDUMP\PRINTER1' -PRINTER '\\printserver\PRINTER1' -LOGFILE 'C:\scripts\pdfdump.log'"
- Start in: c:\scripts\
- Conditions Tab
- Uncheck everything to ensure it always runs
- Settings Tab
- Check and set:
- Allow task to be run on demand
- Run task as soon as possible after a scheduled start is missed
- If the task fails, restart every: 1 minute
- Attempt to restart up to: 30 times
- If the running task does not end when
- Uncheck
- Stop the task if it runs longer than
- If the task is not scheduled to run again, delete it after
Tuesday, November 12, 2013
IE 11 Realse Breaks Oracle BIS.. Kinda
Every new release of IE brings with it disastrous repercussions to the business environment. I, like many internet security savvy individuals, understand and appreciate the value of keeping browsers up to date and secure. I would love nothing more than to keep our IT environment hacker, virus, and and exploit free by enforcing some form of update policy on all the browsers used on our computers. However, business needs and 3rd party requirements often trump an administrator's ability to do this. One of the biggest culprits is Oracle Business Intelligence Suite.
Today the hellfire began with a user who had followed the prompt, like a good user should, to update IE to the latest version. After doing so, of course, doing anything that utilizes Oracle Forms fails miserably. My experience with the IE 10 upgrades taught me better than to even try getting IE 11 to work with Oracle for at least a few months. So, let's just roll this back to IE 10 or 9 and "make good fix".
...Wait, IE 11? What the hell is that? How, in all my keeping up with windows related updates and such, did I manage to even miss that IE 11 was even on the horizon let alone being released. I remember vaguely hearing about its beta a few months ago but I guess I somehow completely missed this. Oh well.
Anyway, I did what anylazy domain admin would do: I downloaded the Internet Explorer 11 Blocker Toolkit. I added a GPO to block the update (following closely to these instructions for IE 10), linked it to the domain root, set it to enforce, then did a quick reboot on my workstation to ensure it was effective.
This is all well and good for any computer that will be re-logged or rebooted in the next day or so. But, what do we do about all the ones online now to keep them from updating in the next few hours? Laziness is the true mother of invention; I have no desire to keep uninstalling this update over and over. The IE 11 blocker toolkit includes IE11_Blocker.cmd which allows you to apply the block immediately to remote computers. Alas, it only takes a single computer as an argument.
Batch scripting is funny and still foreign to me after almost 2 decades of windows administration (I was really big into VBS because I was also working in web hosting where VB ASP was still hip) but I didn't feel like figuring this out in powershell. I exported a newline-sperated list of computers from our sites OU to a file called comps.txt and now I need a batch script to go through it and run the IE blocker for each one. After some digging around on Google for for-loops and ping tests I finally came up with this:
It's not beautiful, but it gets the job done. Now, how to get this deployed to our remote users who are very rarely connected to the domain network?
Today the hellfire began with a user who had followed the prompt, like a good user should, to update IE to the latest version. After doing so, of course, doing anything that utilizes Oracle Forms fails miserably. My experience with the IE 10 upgrades taught me better than to even try getting IE 11 to work with Oracle for at least a few months. So, let's just roll this back to IE 10 or 9 and "make good fix".
...Wait, IE 11? What the hell is that? How, in all my keeping up with windows related updates and such, did I manage to even miss that IE 11 was even on the horizon let alone being released. I remember vaguely hearing about its beta a few months ago but I guess I somehow completely missed this. Oh well.
Anyway, I did what any
This is all well and good for any computer that will be re-logged or rebooted in the next day or so. But, what do we do about all the ones online now to keep them from updating in the next few hours? Laziness is the true mother of invention; I have no desire to keep uninstalling this update over and over. The IE 11 blocker toolkit includes IE11_Blocker.cmd which allows you to apply the block immediately to remote computers. Alas, it only takes a single computer as an argument.
Batch scripting is funny and still foreign to me after almost 2 decades of windows administration (I was really big into VBS because I was also working in web hosting where VB ASP was still hip) but I didn't feel like figuring this out in powershell. I exported a newline-sperated list of computers from our sites OU to a file called comps.txt and now I need a batch script to go through it and run the IE blocker for each one. After some digging around on Google for for-loops and ping tests I finally came up with this:
@echo off
setlocal enableDelayedExpansion
for /F %%x in ('type comps.txt') do (
ping %%x -n 1 -w 1000 | find "Reply from "
IF NOT ERRORLEVEL 1 IE11_Blocker.cmd %%x /B
)
It's not beautiful, but it gets the job done. Now, how to get this deployed to our remote users who are very rarely connected to the domain network?
Subscribe to:
Posts (Atom)