2

I'm using BITS to transfer file from one windows 2008 R2 server to the other. When I run the command manually from powershell or regular command line it works perfectly. Now when I use the same command as part of a build script in Jenkins it fails with the following error :

Start-BitsTransfer : Cannot find path '\192.168.1.210\C$' because it does not exist.

Jenkins runs as a windows service under "Local System" account. I thought changing the windows service to run under "Network Service" account might help, but that's not the case either.

Is there's some security reason which does not allow BITS to run from a windows service?

Here's the Powershell script I have deploy.ps1:

Function Get-PSCredential($User,$Password)
{
 $SecPass = convertto-securestring -asplaintext -string $Password -force
 $Creds = new-object System.Management.Automation.PSCredential -argumentlist $User,$SecPass
 Return $Creds
}

$credential = Get-PSCredential -User jenkins -Password jenkins

Import-Module BitsTransfer
Start-BitsTransfer -source c:\file.zip -destination \\192.168.1.210\C$\Website -credential $credential

Confirming again, the above powershell script works perfectly fine when i trigger it manually myself using powershell or windows command.

This is the command I use in Jenkins to trigger the script:

Powershell.exe -noprofile -executionpolicy Bypass -file C:\deploy.ps1 
newbie
  • 763
  • 1
  • 10
  • 12

4 Answers4

2

Probably not the answer you were hoping for:

When you use *-BitsTransfer cmdlets from within a process that runs in a noninteractive context, such as a Windows service, you may not be able to add files to BITS jobs, which can result in a suspended state. For the job to proceed, the identity that was used to create a transfer job must be logged on. For example, when creating a BITS job in a PowerShell script that was executed as a Task Scheduler job, the BITS transfer will never complete unless the Task Scheduler's task setting "Run only when user is logged on" is enabled.

From MSDN, where it seems like it's not possible...

landonz
  • 311
  • 2
  • 4
1

Remember that the 'C$' share is an administrative share, ie. only visible and accessible by administrators. So unless the service account running the Jenkins service has local admin permissions on 192.168.1.210, you're going to get this error -- because it actually cannot find the specified path.

Try running the Jenkins service as a domain account that has local Admin on the target server as a test, and you should see the behavior change. Then you would just need to determine what permissions your Jenkins service account needs.

Alternatively, you could try sharing out the 'Website' folder as a non-administrative share and see if Network Service can access that. (You might then need to give the source computer accout NTFS access to the folder).

jbsmith
  • 1,291
  • 7
  • 13
  • $credential = Get-PSCredential -User jenkins -Password jenkins is the administrator account on the remote machine. Seems like this credential is not used and instead the windows service account running Jenkins is used? So what is the point of specifying credentials with BITS? – newbie Jun 05 '13 at 00:45
  • Yeah, from my quick testing it looks like Start-BITSTransfer uses the current credentials to find the target location, and only once it's found it does it use the user-specified credentials to actually initiate the transfer. Which doesn't seem right to me; but it does mean that you're not going to see a "xxx$" share unless the service account has local admin on the target location. I'd try sharing out the target share as a non-administrative share and see what that gets you. I think the service account only needs to SEE the share, not have access to it. – jbsmith Jun 07 '13 at 15:26
0

Bsaed on the fact that it starts with a single backslash in the error message, it looks like an escaping problem. PowerShell has an annoying habit of treating anything that begins with a backslash \ as a regular expression.

Try escaping that parameter. Three possible ways come to mind:

  1. Simply escape the first backslash:

    `\\192.168.1.210\C$\Website
    
  2. Single quote the whole parameter (don't double quote it because $ is treated specially in double quoted items):

    '\\192.168.1.210\C$\Website'
    
  3. Double all the backslashes:

    \\\\192.168.1.210\\C$\\Website
    
Michael Hampton
  • 237,123
  • 42
  • 477
  • 940
  • Nah that didn't work, I tried all 3 ways.. It's not a problem with the escaping. It somehow is not able to find the path when executed from a windows service. – newbie Jun 01 '13 at 22:21
  • In PowerShell, the escape symbol is a backtick `, so doubling backslashes won't fix the issue. – Dodzi Dzakuma Apr 25 '19 at 14:40
  • 1
    @DodziDzakuma Hi, this answer is almost six years old, and I'm still a mostly Linux admin. I'm happy to hear about any method which does work if you know of one! – Michael Hampton Apr 25 '19 at 14:46
0

As landonz replied, at first, that can't be done. But that actually can be done, if you're willing to go through the hoops.

Read this: Service Accounts and BITS - "... You can use BITS to transfer files from a service. The service must use the LocalSystem, LocalService, or NetworkService system account. These accounts are always logged on; therefore, jobs submitted by a service using these accounts always run. ..."

spuk
  • 129
  • 2