Home > Development, General, Powershell, Scripting > BITS Transfers via PowerShell

BITS Transfers via PowerShell

I’ve recently decided to make a change and move over from client automation / deployment to the server side.  I’ll be doing similar functions just on servers now instead of on workstations.  Automation is automation if you ask me.  It doesn’t really matter where it’s done.  Given the change I’ve found that I’ll probably need to pick up PowerShell now so I started fooling around with it a little.  I started simple with just configuring static network information and renaming network connections based on a certain standard.  That was ok, but done mostly via WMI in PowerShell.  I’ve already done a lot with WMI in VBScript, so it was only partially satisfying.  While it was a good start to ease in, I wanted something that was all PowerShell.  Then someone posed a question to me about transferring files via BITS.  I’ve never done anything programmatic with BITS before and found a nice little stash of BITS cmdlets within PowerShell!  That was my chance to do something new.   While it’s not perfect it’s one of the only BITS scripts I could find that starts a transfer asynchronously and waits until the files are transferred then completes the job automatically while giving status along the way.  The only gotcha is it needs to run as “the administrator” on Windows 7 and Server 2008, I’ve not tested it on Vista but I’d assume you’d need to do the same on that.  Not all functions need to be run as admin.  Just creating a transfer job doesn’t need it, but when you start getting into suspending, resuming, checking status, etc it’s needed.  That being the case I think it’s just easier to say if you’re going to run it, just do a “Run as Administrator”.  Because of the signing rules with PowerShell I’ll just post the code for it and let you copy and paste it into a file yourself. 

Quick feature run down:

  • Create BITS job asynchronously and wait for it to complete giving status along the way.
    • Percent complete
    • Number of total files to copy and how many have completed.
    • Total bytes to copy and how much has been copied so far.
  • Use wild cards for your source if you want to copy multiple files.
  • Suspend, Resume, Complete, or Cancel existing BITS jobs.

I’ve used the script to copy *.csv or *.exe or my favorite *m* (every file with an “m” in the name somewhere).  Granted you can’t do the combos above in one job but you can do them in multiple jobs.  If I want to run multiple jobs I’ll just create a new one and then while the progress is showing hit Ctrl+C to break out and start the next.  The down side to this is the job(s) will not auto-complete now, but that’s why I added the –status and –complete switches.  I just check back later with a –status and all of the jobs marked as “transferred” I run it again with a –complete [Job Name].

Speaking of switches these are the ones I’ve made available:

  •  [ScriptName] -create ‘[Job Name]’ ‘[Source]’ ‘[Destination Folder]’
    • Creates a BITS transfer job and waits until it finishes so it can automatically complete it (hit Ctrl+C during the status output to cancel the script.  The created job will continue, but it won’t auto complete).   Spaces are ok in any of the parameters you just must enclose them in quotes, single or double it doesn’t matter which.
  • [ScriptName] -status
    • Gets the current status of existing BITS jobs.
  • [ScriptName] –complete ‘[Job Name}’
    • Completes the job specified by the parameter.
  • [ScriptName] –suspend ‘[Job Name]’
    • Suspended or pauses the job name specified.  It will need to be either canceled or resumed later.
  • [ScriptName] –resume ‘[Job Name]’
    • Resumes an existing suspended BITS job.
  • [ScriptName] –cancel ‘[Job Name]’
    • Cancels the specified job.  It can be currently running or suspended.
  • [ScriptName] –help
    • Displays help info and switch syntax.

================= PowerShell Code =================

Import-Module BitsTransfer

If($args.Count -lt 1 -or $args[0] -eq “-help”)

{

      “”

      “================================================================”

      “To create a transfer job:”

      “”

      “Please provide in this order: [Job Name] [Source] [Destination]“

      “”

      “Example: ” + $MyInvocation.MyCommand.definition + ” ‘Test Copy’ ‘C:\Source Test\*’ C:\Destination\”

      “”

      “The above example will copy all FILES from the source folder to the destination folder.  Only files are copied, folders are NOT copied.”

      “”

      “NOTE: If parameters have spaces in them, they MUST have quotes around the parameter.  It doesn’t matter if they are single or double quotes.”

      “”

      “================================================================”

      “”

      “To view job(s) status:”

      “”

      “Example: ” + $MyInvocation.MyCommand.definition + ” -status”

      “”

      “================================================================”

      “”

      “To complete transfered job(s):”

      “”

      “Please provide in this order: -complete [Job Name]“

      “”

      “Example: ” + $MyInvocation.MyCommand.definition + ” -complete ‘Test Copy’”

      “”

      “================================================================”

      “”

      “To view job(s) status:”

      “”

      “Example: ” + $MyInvocation.MyCommand.definition + ” -status”

      “”

      “================================================================”

      “”

      “To suspend a job:”

      “”

      “Please provide in this order: -suspend [Job Name]“

      “”

      “Example: ” + $MyInvocation.MyCommand.definition + ” -suspend ‘Test Copy’”

      “”

      “================================================================”

      “To resume a suspended job(s):”

      “”

      “Please provide in this order: -resume [Job Name]“

      “”

      “Example: ” + $MyInvocation.MyCommand.definition + ” -resume ‘Test Copy’”

      “”

      “================================================================”

      “To cancel a job:”

      “”

      “Please provide in this order: -cancel [Job Name]“

      “”

      “Example: ” + $MyInvocation.MyCommand.definition + ” -cancel ‘Test Copy’”

      “”

      “================================================================”

Exit

}

If($args -eq “-complete”)

{

      $bitsJob = Get-BitsTransfer -AllUsers -Name $args[1]

      Complete-BitsTransfer -BitsJob $bitsJob

      If($Error.Count -eq 0)

      {

            “”

            $args[1] + ” completed….”

            “”

      }

      Get-BitsTransfer -AllUsers

      $Error.Clear()

}

If($args -eq “-status”)

{

      $bitsJobs = Get-BitsTransfer -AllUsers

      ForEach($job in $bitsJobs)

      {

      “************************************************************************”

      “”

      “Job Name: ” + $job.DisplayName

      “Job Start Time: ” + $job.CreationTime

      “Job State: ” + $job.JobState

      “Files Copied: ” + $job.FilesTransferred + ” of ” + $job.FilesTotal

      If($job.BytesTotal -ne 0)

      {

      $bitsStatus = $job.BytesTransferred / $job.BytesTotal

      “Percent Complete: {0:P1}” -f $bitsStatus

      }

      “Copied: ” + $job.BytesTransferred + ” of ” + $job.BytesTotal + ” Bytes”

      “”

      }

      “************************************************************************”

}

If($args -eq “-suspend”)

{

      $bitsJob = Get-BitsTransfer -AllUsers -Name $args[1]

      Suspend-BitsTransfer $bitsJob

      If($Error.Count -eq 0)

      {

            “”

            $args[1] + ” suspended….”

            “”

      }

      $Error.Clear()

}

If($args -eq “-resume”)

{

      $bitsJob = Get-BitsTransfer -AllUsers -Name $args[1]

      Resume-BitsTransfer $bitsJob -Asynchronous

      If($Error.Count -eq 0)

      {

            “”

            $args[1] + ” resumed….”

            “”

      }

      Get-BitsTransfer -AllUsers

      $Error.Clear()

}

If($args -eq “-cancel”)

{

      $bitsJob = Get-BitsTransfer -AllUsers -Name $args[1]

      Remove-BitsTransfer $bitsJob

      If($Error.Count -eq 0)

      {

            “”

            $args[1] + ” canceled….”

            “”

      }

      Get-BitsTransfer -AllUsers

      $Error.Clear()

}

Function StartFileTransfer

{

      $bitsCopy = Start-BitsTransfer -DisplayName $bitsJobName -source $bitsSource -Destination $bitsDestination -Asynchronous

      $bitsStartTime = $bitsCopy.CreationTime

Do

{

      Clear-Host

      “****** BITS Job ” + $bitsJobName + ” ******”

      $bitsStatus = $bitsCopy.BytesTransferred / $bitsCopy.BytesTotal

      “Job Start Time: ” + $bitsStartTime

      “Job Name: ” + $bitsJobName

      “Transfering: ” + $bitsSource + ” to ” + $bitsDestination

      “Currently copying file ” + $bitsCopy.FilesTransferred + ” of ” + $bitsCopy.FilesTotal

      “Percent Complete: {0:P1}” -f $bitsStatus

      “Copied: ” + $bitsCopy.BytesTransferred + ” of ” + $bitsCopy.BytesTotal + ” Bytes”

      sleep -Milliseconds 500

}

Until($bitsCopy.JobState -eq “transferred”)

      “Percent Complete: 100.0 %” + ” ” + $bitsCopy.FilesTransferred + ” of ” + $bitsCopy.FilesTotal + ” files copied.”

      “Commiting Job: ” + $bitsJobName

      $bitsEndTime = $bitsCopy.TransferCompletionTime

      Complete-BitsTransfer -BitsJob $bitsCopy

      “Job End Time: ” + $bitsEndTime

      “****** BITS Job ” + $bitsJobName + ” Completed ******”

}

If($args -eq “-create”)

{

      $bitsJobName = $args[1]

      $bitsSource = $args[2]

      $bitsDestination = $args[3]

      $fileCount = -1

      StartFileTransfer

}

 

Advertisement
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.