Downloading the Latest Dell Driver Packs with PowerShell

It was a regular Tuesday morning and I hadn’t yet had my ‘PowerShell fix’ for the week, so when I realised I needed to download a new driver pack from Dell for my ConfigMgr OS deployments, I could hear a faint voice calling out to me: ‘Dude, I can make your life easier! Work smarter, not harder!

Of course, that’s only ever partially true, because with PowerShell you must work harder today in order to work smarter tomorrow, but in the interest of long-term benefit I proceeded to fire up the ISE.

Suddenly, a thought arose from my subconscious: ‘Wait just a second. Don’t re-invent the wheel.  Aren’t there already some good solutions out there for this?

Well yes, that’s true,‘ my internal musings continued. ‘Most notably, we have a very cool tool by Maurice Daly – the Driver Automation Tool. With this we can just click buttons and go get coffee while the tool does all the hard work. It’ll even import the driver packs into SCCM. I like that!

Yes that is awesome.‘ I responded to myself, ‘Problem is, I still need a PowerShell fix. So maybe I can find a different way of downloading driver packs. What do you suggest?

Well, we have the Dell Driver Pack Catalog. Dell even provide examples of how to use that with PowerShell to find the URLs you need to download the relevant cab files.

Yes, this is cool too. But I think there is still another way. Doesn’t Dell’s TechCenter wiki contain the download URLs for the most recent driver packs?

Yes, it does. But you want to use PowerShell, right?

Correct.’

So what are you thinking?

Web-scraping.

Ah, you bad boy! Let’s do it!

Dell maintains a wiki page containing links to the latest driver packs which can be found here:

http://en.community.dell.com/techcenter/enterprise-client/w/wiki/2065.dell-command-deploy-driver-packs-for-enterprise-client-os-deployment

You simply find the model and operating system version you want and click the link, which leads you to another wiki page containing a download URL.

Rolling up the sleeves, I whipped up some code that will scrape these web pages to find the download URL for the current driver pack version and download it using a BITS transfer. You can then import or add the driver pack into ConfigMgr for OSD using your favourite method (which is PowerShell, right?!)

The resulting script is quite simple to use and works reliably in my testing, although it takes a few seconds to filter the HTML in order to find the appropriate download URL.

You can download a driver pack for a single model, for example:


Download-LatestDellDriverPack -Model "Latitude E7470" -OperatingSystem 'Windows 10' -DownloadDirectory C:\DriverPacks -Verbose

Just provide the model name, operating system version and a location to save the downloaded file to. Support is provided for verbose output.

You can also pass a list of models to the script and it will download each one in turn, for example:


"M4800","Optiplex 9020","E6420","E5250" | Download-LatestDellDriverPack -OperatingSystem 'Windows 7' -DownloadDirectory C:\DriverPacks -Verbose

drivers
The script in action

The script will work for any driver pack with an operating system Windows 7 or higher (are you really deploying anything older than that?!), and there is no proxy support currently.

Here’s the full script:

ConfigMgr Content Distribution Fails with 0x80041001

Today I came across an unusual issue on a couple of SCCM distribution points where two particular software update packages were failing to distribute. Using the distmgr.log and the PkgXferMgr.log on the site server, as well as the Distribution Point Job Queue Manager tool, I could see that these packages were trying to distribute again and again, but returning a failure on certain files.

In the PkgXferMgr.log I found these entries repeatedly:


ExecStaticMethod failed (80041001) SMS_DistributionPoint, FinalizeContent
CSendFileAction::SendContent failed; 0x80041001
Sending failed. Failure count = 2, Restart time = 24/04/2017 15:30:57 W. Europe Daylight Time

0x80041001 is a WMI error meaning “Generic failure” – not overly helpful.

So I went to the distribution point itself to investigate, and found these entries repeatedly in the smsdpprov.log


[BA4][Mon 04/24/2017 22:24:19]:MoveFile failed for \\?\C:\SCCMContentLib\DataLib\24688509-2940-44e9-9d7d-9a6c2e33c9a1.ABC002C2.temp to \\?\C:\SCCMContentLib\DataLib\24688509-2940-44e9-9d7d-9a6c2e33c9a1
[BA4][Mon 04/24/2017 22:24:19]:FileRename failed; 0x80070005
[BA4][Mon 04/24/2017 22:24:19]:CContentDefinition::Finalize failed; 0x80070005
[BA4][Mon 04/24/2017 22:24:19]:Failed to finalize content '24688509-2940-44e9-9d7d-9a6c2e33c9a1' for package 'ABC002C2'. Error code: 0X80070005

0x80070005 means “access denied”. So I browsed to the location in Explorer and sure enough:

pic

If I try to view the Security tab on the directory, apparently I don’t have permission:

pic2

If I click Advanced, it seems we don’t have an owner, so clearly something is corrupted as the other files and directories in this location are owned by the SYSTEM account.

pic3

If I try to change the ownership in the UI, nothing happens.

So I use PSEXEC to open a cmd prompt in SYSTEM context, and try to take ownership on one of the directories, but still no joy:

pic4

Next I run Process Explorer to find if something has a handle on it, and yes, WMI does.

pic5

So I stop the WMI service, and suddenly the directory disappears!

Start the WMI service (and it’s dependencies) and then kick off the distributions again using the DP Job Queue Manager tool, and finally the packages distribute successfully 🙂

Backup and Restore ConfigMgr Site Maintenance Task Settings with PowerShell

According to the official Microsoft documentation, when upgrading to System Center Configuration Manager (current branch), it is recommended to disable any site maintenance tasks that could run during the upgrade (as they can cause the upgrade to fail), and to make a record of the task schedules for any disabled tasks:

Before you disable a task, record the schedule of the task so you can restore its configuration after the site upgrade completes.

Since I don’t want to manually note down the schedules for my maintenance tasks, I wrote a couple of PowerShell scripts to backup and restore the site maintenance task settings for me.

The backup script will export the settings for each site maintenance task and save them to file in json format.

The restore script will then read each backup file, compare the current settings in WMI with the backed-up settings for each maintenance task, and update anything that doesn’t match. The script will tell you if anything has changed and what the old and new values are.

If you run the backup before you disable the tasks, the restore script will re-enable them again.

Both scripts should be run elevated on your primary site server.

Backup-CMSiteMaintenanceTaskSettings

To backup, simply pass the sitecode and the backup directory to the script:


Backup-CMSiteMaintenanceTaskSettings -SiteCode ABC -BackupDirectory G:\Backup\SiteMaintenanceTasks

You will then see a json file for each site maintenance task in the backup directory:

jsonfiles

Restore-CMSiteMaintenanceTaskSettings

To restore, pass the same parameters to the script:


Restore-CMSiteMaintenanceTaskSettings -SiteCode ABC -BackupDirectory G:\Backup\SiteMaintenanceTasks

The script will read each file then compare the settings with the current task settings in WMI. If there are any differences, these will be updated and reported:

restore

Scripts