TFS Release, running PowerShell, cannot create DtlDownloads - tfs

I am trying to get some automatic deployments up and running using TFS 15 (on-premise). I have a powershell script on the deployment target to call.
The deployments starts fine by downloading the artifact. But when the agent runs the script it wants to create a folder C:\Windows\DtlDownloads (thats not part of my script but part of preparing things for TFS I guess). That fails:
##[debug]System.AggregateException: Failed to install 'VisualStudioRemoteDeployer20597940-38b2-4ba8-9a4d-fcc894308730' from service executable path VisualStudioRemoteDeployer.exe . Consult the logs below:
Access to the path 'DtlDownloads' is denied.
CategoryInfo :PermissionDenied: (C:\Windows\DtlDownloads:String) [New-Item], UnauthorizedAccessException
FullyQualifiedErrorId :CreateDirectoryUnauthorizedAccessError,Microsoft.PowerShell.Commands.NewItemCommand
The user used to logon is a server-local user named deploy who is also a local administrator on that machine. I also checked the effective access for that user on the windows folder and it should be able to create directories.
Something similar happens with the copy step. Robocopy signals two errors:
2017/03/16 08:57:21 ERROR 5 (0x00000005) Getting File System Type of Destination \\server.domain.com\c$\abc\def\
Access is denied.
and
2017/03/16 08:57:21 ERROR 5 (0x00000005) Creating Destination Directory \\server.domain.com\c$\abc\def\
Access is denied.
The second is a bit unexpected as the folder def already exists but I guess it is a follow up because getting the type failed beforehand.
The user itself must have been recognized because I get different errors when using invalid credentials. I have enabled WinRM using Enable-PSRemoting and ConfigureWinRM.ps1 from WinRM-Http-Https-Without-Makecert.
What could still restrict the permissions?
Update: Using a domain user instead of a local one of that server solves the issue. But I do not understand why. Can someone explain or even provide information how to make it work with a local user?

The username of either a domain or a local administrative account on
the target host(s).
Formats such as username, domain\username, machine-name\username, and .\username are supported.
UPN formats such as username#domain.com and built-in system accounts such as NT Authority\System are not supported.
Source Link
Both the domain account and local admin should be work. Please double check your format and give a try with another format.

One problem could be if that you have the agent as a service, that service has not the proper privileges, like being on Network Account. Try to change that to the user account which has administrative privileges.

Running "winrm quickconfig" fixed this problem for me
winrm quickconfig
https://learn.microsoft.com/en-us/windows/win32/winrm/installation-and-configuration-for-windows-remote-management

Related

Windows service - use domain account and run with admin privileges

I'm trying to set up a Windows service with the following requirements:
Runs as a domain account - this account has access to other shares that the process will touch
Has full administrative rights on the machine, past UAC - specifically needs to be able to take ownership of folders
The problem is that the process needs to take ownership of folders at some points, which is done by calling takeown /A /F <file>. This works on the command line, but only when it's explicitly Run as Administrator - being a local admin on the machine does not give full admin rights, and the account still has to go through the UAC prompt, so when running as a service we just get ERROR: The current logged on user does not have administrative privileges.. It seems like the standard way to get around UAC for a service account is to use the Local System account, but that isn't an option because then we can't access the other servers.
Is there any way to set up the service and say "Run as this account, in the context of a full administrator on the machine"? As another potential solution, is there a way to exclude a domain account from UAC on a machine? Any other solution could work as long as it runs as a service, can set folder ownership, and using a domain account. Ideally this is done without opening up big security holes, like fully disabling UAC on the machine.
I am not able to reproduce your problem. Here is how I tested.
Part 1: Create sample directory with non-administrator owner
Create directory C:\TestDir
Disable permission inheritance and copy inherited permissions into explicit permissions
Grant NT SERVICE\TrustedInstaller full control access
Set owner of directory to NT SERVICE\TrustedInstaller
Set Administrators and SYSTEM accounts to have read access
Remove access for all other accounts
After complete, verify that, logged on as elevated administrator, I am not able to create a file in that directory.
Part 2: Create a service that takes ownership of the directory
I did this using nssm (https://nssm.cc):
Create a short batch file, C:\scripts\TestService.cmd, containing the takeown command:
takeown /F C:\TestDir /A
Run nssm install and specify:
Application path: C:\Windows\System32\cmd.exe
Arguments: /C C:\scripts\TestService.cmd
Restart action: Stop service (oneshot mode)
Log on: Specify username and password of an account that's a member of the local Administrators group
stdout redirection: C:\scripts\TestService-stdout.log
stderr redirection: C:\scripts\TestService-stderr.log
I started the service, which executed the C:\scripts\TestService.cmd batch file. (The service stopped immediately after starting, which is expected in this case.) The standard output file C:\scripts\TestService-stdout.log contained the following lines:
C:\Windows\System32>takeown /F C:\TestDir /A
SUCCESS: The file (or folder): "C:\TestDir" now owned by the administrators group.
This experiment demonstrates that a service running using an account that's a member of the local Administrators group runs elevated (i.e., with full administrative privileges).

TFS (On-premises) - Deploy: Windows Machine File Copy

My question is - to copy files to remote machines from the Drop folder, do I need that remote machine registered as an agent?
My remote machine is in the same network but still, I'm getting an ERROR to copy files.
No, it is not required to have a TFS Agent on the target server in order to copy files over to it, but you do need to have permission to write to it. See the screenshot of what I did. Notice that I am storing the credentials as variables in the build definition. The password is "locked" so no one can see the clear text password. I have the Build Agent running under the same service account that has Admin privileges on the target server, but leaving them off did not help. To test this out, try to log into the build server via RDP and then try to open file explorer and connect to the Target Server using the network path (\SomeServer\C$\SomePath\dir) and using the credentails (domain\login or just login) and see if it works, along with the password.

Jenkins - remote access denied

I'm using the ArtifactDeployer plugin to deploy the build job artifacts to a remote location (Windows share SMB).
However Jenkins never manages to succeed. Throwing errors like:
[ArtifactDeployer] - Starting deployment from the post-action ...
[ArtifactDeployer] - [ERROR] - Failed to deploy. Can't create the directory ... Build step
[ArtifactDeployer] - Deploy artifacts from workspace to remote directories' changed build result to FAILURE
Local deployment works fine.
The Jenkins machine OS is Windows 7 32-bit Prof.
Jenkins is running as a service using a local system account.
I tried using another account, my user account but the service failed to start (Windows error 1069: the service did not start due to a logon failure).
The network service account did run but than Jenkins throws errors it can't access the .NET framework.
When manually trying the remote copy, this works fine. I can create directories and write to it. On the same machine of course.
I tried two different remote reference in Jenkins:
1) \\targetdirectory
2) I:\ - by mapping a drive letter to the remote dir in windows
No success...
Any tips or suggestions? Thanks!
Update 15/02/2012:
Still no solution or workaround for this issue.
It's not only the plugin, I hit also this issue using "Execute Windows batch command".
I found a bug report that I want to share.
Solution
I found a solution. You have to grant access persmission to the computer in a domain instead of the user of that machine. Seems very logic if you look back to it.
A 2nd solution is to run the service using a domain user account. Above I made a mistake by using the local user .\user in stead of DOMAIN\user.
If you don't have a domain, the following will work for sure. This should work even if you have a domain.
Background Info:
You need your mapped drive to be mapped for the same account that the service is using AND be available at the right time. Normally mapped drives are mapped only for the logged in user, at the time that they log in. Service user contexts don't get "logged in" per se -- for example, if I map a drive as MyUser and the service runs as MyUser, the drive won't be available until I actually log in by typing in my password. However, we can use a script to map the drive at startup (instead of login) for a particular user. Jenkins normally runs as Local System Account, so if you don't want to change that, you'll need to run the script below as the SYSTEM user. You can instead create a specific user for Jenkins to run as, if you don't want to grant this mapped drive to all services/processes that run as SYSTEM, and run both the service and the script below as that user (this is probably more secure).
Solution Steps:
In ArtifactDeployer you want to deploy to a mapped network drive. In my case this is S:.
There is no special setup for permissions on the remote share. (In my case, a Windows Server 2008 share with a username and password that is used for mapping the drive.)
Write a batch file MapDrives.bat in a place that your chosen user (default: SYSTEM) has access to, with the following in it:
net use S: "\\server_name\share_name" /persistent:yes password_here /USER:username_here
Note that I am mapping to S: in that line.
Via Task Scheduler, create a task that runs as the same user as the service (default: SYSTEM), triggers At Startup, and as it's action, runs the batch file MapDrives.bat.
Reboot and it should work!
Citations:
After diving through many pages and many tests, ultimately, the best suggestions were found here, and led me to the above solution.
https://stackoverflow.com/a/4763324/150794
Make sure your 'local system account' has access rights to the remote directory (including write access). Then use the notation
\\targetdirectory
Mapping drive letters to remote directories only applies to the user account you are currently working with. The drive letter mapping will not be available to any other account.

Using MsDeploy to deploy Windows Services with preSync command

Is anyone successfully using MsDeploy for deploying windows services with a preSync runCommand? I've got it working using an Administrator account, but can't for the life of me get it working on a standard user account. Unfortunately I can't use integrated authentication (we're deploying to an external box), and the thought of our Administrator password sitting in plaintext in logs on our build server doesn't exactly make me feel too comfortable. For that matter, neither does any user credentials - but I can't see a way around that.
The command I'm using is this:
"tools/deploy/msdeploy.exe" -verb:sync
-preSync:runCommand="tools\Deploy\PreSyncCommand.cmd",waitInterval=30000
-source:dirPath="C:\BuiltSourcePath"
-dest:computerName=https://server:8172/msdeploy.axd?site=dummysitename,userName=service-deploy,password=service-deploy-pass,authType=basic,dirPath="C:\DeployPath\"
-allowUntrusted
with rules set up in IIS for the dummy site to allow the authentication for the service-deploy windows account, with contentPath and runCommand permissions (for the moment set to C:\ as it's not entirely clear whether this needs to be set to the temporary path that MsDeploy streams to, or the deployment path?). The service-deploy account also has full control of the target directory. I get the following back:
Performing '-preSync'...
Info: Using ID '7a7d34a1-b5d8-49f1-960a-31c9cf825868' for connections to the remote server.
Info: Using ID '4d0b910c-aca4-4640-84bd-3597d22d99d1' for connections to the remote server.
Info: Updating runCommand (C:\TeamCity\buildAgent\work\aec989676b349656\tools\De
ploy\PreSyncCommand.cmd).
Warning: Access is denied.
Warning: The process 'C:\Windows\system32\cmd.exe' (command line '/c "C:\Windows
\ServiceProfiles\LocalService\AppData\Local\Temp\giz2t0kb.0ay.cmd"') exited with
code '0x1'.
This happens even if the contents of PreSyncCommand.cmd is blank. The same command runs fine if I pass in Administrator credentials. I've tried using ProcessMonitor to check if anything's being denied access but can't see any - so I'm guessing it's still a MsDeploy authentication rule. There's nothing in WmSvc.log (debugging is enabled), nor in the event log.
Any ideas? Thanks!
Since you're using Web Deploy via WmSvc, you need to setup appropriate delegation rules on the destination server:
Within IIS Manager, open the "Management Service Delegation" feature. Add a new rule which at least specifies the runCommand provider. In the Run As section, choose Specific User and provide credentials for a local administrator account on that machine. This is the identity under which your runCommand scripts will be executed. Finally, the user which you're specifying for the destination dirPath provider needs to be added to the delegation rule.
That allows you to invoke a deployment using a non-privileged account, and yet have it executed on the target machine under administrative credentials.
More information on IIS feature delegation: http://learn.iis.net/page.aspx/516/configure-the-web-deployment-handler/

copy files from network via windows service

I have batch files, its copy some files from network to local disk. When try to run it from a windows service I get an error like "Access Denied".
I already try run windows service as LocalSystem , LocalService and NetworkService. All these types get same error.
Have any idea ?
Thanks
NetworkService is the only one that is going to include network credentials here, and that will be the local machine's identity. Does the machine account have access to the share? If this isn't correct, you'll need to run the service as a dedicated, specific user account.
What version of windows is this ? And have you checked the effective ACL settings of the shared files/folders ?
Try changing the ACL on the shared resource to allow everyone access...
If that works you need to give DOMAIN\networkservice the correct permissions. In this case both machines would need to be in the correct domain.

Resources