Troubleshooting BITS with PowerShell

This month's segment is going to focus on troubleshooting BITS downloads.  Many folks may be familiar with using BITSAdmin to troubleshoot BITS transfers and errors.  However, this command is deprecated.  Never fear, there are some PowerShell commands that we can use and I will show you how!

Let's start with getting access to the BITS PowerShell CmdLets.  To do this, we need to import the BITSTransfer module.

Import-Module BITSTransfer

Now let's see what commands are available.  I like to use the get-help feature because it's easier for me to remember.

get-help *bits*

This command will list any commands with "bits" in the name. 

Please note, this will not always show you all the commands in a module.  For those cases, this command would be appropriate: Get-Command -Module BITSTransfer

Now that we know the commands available, let's explore the ones relevant to our task.  We are going to start with

 Get-BitsTransfer -AllUsers

We need to use the -AllUsers because the ConfigMgr jobs are owned by "System".  Without this argument only jobs performed by the current user would be present.

We can see in the output, that I have 2 jobs that are in Error state.  Let's get some more information about these jobs using

Get-BitsTransfer -AllUsers | select *

We can see each job and all the associated properties.  We can see we have an ErrorDescription that shows a HTTP status 404. 

If you are familiar with BITS download issues and using BITSAdmin, you may have seen this before. 

The next property we want to pay attention to is FileList.  In this view, we can't see all the FileList information, so we need to execute a few other commands.  To look inside the FileList, we need to expand it

Get-BitsTransfer -AllUsers | select -ExpandProperty FileList

This command might have a long result set as it returns each file that is being transferred in each BITS job.  It might be a good idea to output this to a file.

Get-BitsTransfer -AllUsers | select -ExpandProperty FileList | Out-File C:\bits.txt

As we look at the results, we can see a pattern.  Each section list information about each file copied or being copied.  We want to pay close attention to the RemoteName and BytesTransferred properties.

We can see at the highlighted row that the RemoteName "OSDResults.exe.config" has a BytesTransferred of 0.  All the files before this item have a valid file size.  This tells me that most likely this is the file that is causing the BITS job to Error. 

This is due to RequestFiltering rules that are setup on BITS enabled DPs.  In order to fix this, you need to modify the applicationHost.config file to allow these types of files to be transferred.\#Config\_RequestFiltering
(This is a ConfigMgr 2007 issue as it relies on the IIS WebDAV feature that has this filtering turned on by default)

We can use PowerShell to help streamline this process so we don't have to output to a log file and search for our 0 BytesTransferred. 

Get-BitsTransfer -AllUsers | foreach {get-bitstransfer -jobid $_.jobid | select -ExpandProperty FileList | where {$_.BytesTransferred -eq 0} | select -first 1}

This command is a little more complex, but shows us the files that we need to investigation for each BITS job.  In our example, the same file in both BITS jobs is causing the issue.

Let's break down the command:

Get-BitsTransfer -AllUsers |   This one is straight forward, like the example above, this command returns the BITS Jobs
foreach {get-bitstransfer -jobid $_.jobid | This foreach loop takes each one of the JobID's from the previous command and gets the specific information for that job.
select -ExpandProperty FileList | Again, we need to look inside the FileList property so we select and expand it.

where {$_.BytesTransferred -eq 0} | We want to filter our results and look for items with BytesTransferred is equal to 0
select -first 1} And we want to return only the first result that matches the filter.  We can increase the count here, but most likely the first result returned is our problem file. 

Now we can use those PowerShell skills to help us find files in BITS jobs that may be causing problems.