TFS 2017 - Run powershell script from TFS server, not agent - powershell

Is there a way to run a powershell script from the actual TFS server during a release? I am running the build agent in a docker container and it's not joined to the domain so wmi won't allow the windows agent in the docker container to stop the app pool on the webserver before copying over new artifact files, even though I specify credentials before connecting. If I could run the powershell script from the TFS 2017 server this problem would be solved.
The error I get is:
019-08-30T13:49:44.6542238Z ##[error][<server>.<domain>.com] Connecting to remote server <server>.<domain>.com failed with the following error message
: The WinRM client cannot process the request. If the authentication scheme is different from Kerberos, or if the
client computer is not joined to a domain, then HTTPS transport must be used or the destination machine must be added
to the TrustedHosts configuration setting. Use winrm.cmd to configure TrustedHosts. Note that computers in the
TrustedHosts list might not be authenticated. You can get more information about that by running the following
command: winrm help config. For more information, see the about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (<server>.<domain>.com:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : ServerNotTrusted,PSSessionStateBroken

I kept ignoring the docker windows servercore tfs agent container thinking it must have something to do with the server I'm trying to copy files to but it wasn't. For some reason all I had to do was add the following to my tfs agent:
winrm set winrm/config/client #{TrustedHosts="machineA,machineB"}
Now everything works. I removed all trustedhosts from wsam and it still works. I guess because I'm using credentials in my powershell scripts...not sure but I'm happy.

Related

Powershell Function App- Invoking Azure VM from Visual Studio installed in Azure VM

I have a function app written in PowerShell and when I am trying to run the function app from Visual Studio Code I am getting below error:
OpenError: [VMName] Connecting to remote server VMName failed with the following error message : The WinRM client cannot process the
request because the server name cannot be resolved. For more information, see the about_Remote_Troubleshooting Help topic.
I have Visual Studio Code installed in one of the VM from where I am trying to invoke a file in another VM using PowerShell.
I tried to restart WinRm, add certificates, add the VM as trusted resource, set proxy as 10.0.0.6:8080, did add http and https in inbound rule,etc.
Please let me know if I am missing out on any of the step.

PowerShell on Target Machines Fails in TFS 2018 Release Pipeline

I'm new to TFS2018 and i am trying to configure CI/CD Pipeline. My Build succeeded and in my release pipeline, i need to run powershell script on my deployment server and so i used RUN PowerShell on Target Machine task. I suppose, provided all required info correctly and ran the release but got the error at this task as follows
Connecting to remote server xxx.xxx.xx.xx failed with the following error message : The WinRM client cannot process the request. Default authentication may be used with an IP address under the following conditions: the transport is HTTPS or the destination is in the TrustedHosts list, and explicit credentials are provided. Use winrm.cmd to configure TrustedHosts. Note that computers in the TrustedHosts list might not be authenticated. For more information on how to set TrustedHosts run the following command: winrm help config. For more information, see the about_Remote_Troubleshooting Help topic.
Please find my task config captured below
I tried adding my TFS2018 server as trustedHost on target server but still issue exists. Please suggest and help.
Add the TFS server machine to TrustedHost in Target machine through powershell.
Set-Item WSMan:localhost\client\trustedhosts -value ServerDC
Ensure credentials provided in this task is of admin role and at same time they have access w.r.to TFS in this case. If provided credentials does not have TFS admin previlage, the task cannot invoke agent to trigger VisualStudioRemoteDeployer.
This is what is called the double hop problem with PowerShell, usually it means you are trying to log on to a remote machine with different credentials then the credentials your user is running under. So in your case, is $(adminUserName) the same as the agent? If not then you could try and change that user to be the same as the agent. If not, then you need to do a little more then add the machine to trustedHost. Watch this video on SPN it might help https://www.youtube.com/watch?v=yFgdPcLOs-g and here is a detailed explanation on the double hop issue https://learn.microsoft.com/en-us/powershell/scripting/learn/remoting/ps-remoting-second-hop?view=powershell-7

How can I enter commands in Minecraft server that was run remotely using PowerShell invoke-command on local computer?

I am running a Minecraft server from my laptop since it has an i7 and more RAM than my desktop. I want to be able to see the server command line on my desktop and be able to enter commands while the server is actually running on my laptop. I was able to see the command line by setting up for remote access and running the command
Invoke-Command -ComputerName 10.0.0.53 -Credential Admin -ScriptBlock { & "RUNSERVER.bat"}
This made it so I am able to see what the server is outputting to the PowerShell window on my desktop and the server is running on the laptop like it should be, but I am still unable to enter any commands. I'm pretty inexperienced with PowerShell so I'm not too sure where to go from here. Anyone out there know how I can edit this so that I can input commands from the PowerShell window on my desktop?
[localhost] Connecting to remote server localhost failed with the following error message : WinRM cannot process the request. The following error with
errorcode 0x8009030d occurred while using Negotiate authentication: A specified logon session does not exist. It may already have been terminated.
Possible causes are:
-The user name or password specified are invalid.
-Kerberos is used when no authentication method and no user name are specified.
-Kerberos accepts domain user names, but not local user names.
-The Service Principal Name (SPN) for the remote computer name and port does not exist.
-The client and remote computers are in different domains and there is no trust between the two domains.
After checking for the above issues, try the following:
-Check the Event Viewer for events related to authentication.
-Change the authentication method; add the destination computer to the WinRM TrustedHosts configuration setting or use HTTPS transport.
Note that computers in the TrustedHosts list might not be authenticated.
-For more information about WinRM configuration, run the following command: winrm help config. For more information, see the about_Remote_Troubleshooting
Help topic.
+ CategoryInfo : OpenError: (localhost:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : 1312,PSSessionStateBroken
[localhost] Connecting to remote server localhost failed with the following error message : The WinRM client cannot process the request. CredSSP authentication
is currently disabled in the client configuration. Change the client configuration and try the request again. CredSSP authentication must also be enabled in
the server configuration. Also, Group Policy must be edited to allow credential delegation to the target computer. Use gpedit.msc and look at the following
policy: Computer Configuration -> Administrative Templates -> System -> Credentials Delegation -> Allow Delegating Fresh Credentials. Verify that it is
enabled and configured with an SPN appropriate for the target computer. For example, for a target computer name "myserver.domain.com", the SPN can be one of
the following: WSMAN/myserver.domain.com or WSMAN/*.domain.com For more information, see the about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (localhost:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : -2144108126,PSSessionStateBroken
2019-04-19 20:00:08,630 main WARN Unable to instantiate org.fusesource.jansi.WindowsAnsiOutputStream
2019-04-19 20:00:08,631 main WARN Unable to instantiate org.fusesource.jansi.WindowsAnsiOutputStream
Enter-PSSession -Computername "Laptop"
You are now in a remote powershell session on the machine you identified via the computer name parameter.
Some things to be aware of. If you're doing this in a workgroup and not a domain you're going to need to contend with passing credentials. You have to pass them as a credentials object in PS. So it looks a bit more like this:
$Creds = Get-Credential
enter-pssession -ComputerName 10.0.0.53 -Credential $Creds
for credentials enter a username and PW that exists on the remote machine.
The Firewall on the remote host also needs to be configured to allow inbound Windows Remote Management Framework traffic from your local host.
EDITED THE ORIGINAL ANSWER TO REFLECT MY LATEST ANSWER:
This is where Windows will fall short on these kind of things. Windows by default does not have Pseudoterminal (PTY) support.
Traditionally, in *NIX type systems, you can run ssh -t option to access screen mode (forces TTY).
You might have better luck using this powershell module and following their instructions here: https://github.com/PowerShell/Win32-OpenSSH/wiki/TTY-PTY-support-in-Windows-OpenSSH

How can I access to my own localhost with port number in powershell?

I am writing a script in PowerShell that will automate some actions within an application which is running on my localhost port 81. I need to access this application's content via PowerShell so I can edit and save it.
I learnt a lot about PSSession, but the app I'm trying to reach is on my own machine, not remote. Is there a way to do this?
Edit:
The application I'm trying to reach is TeamCity. I set its port to 81 and to access the application I just need to type http://localhost:81 in my web browser to open TeamCity's UI.
I learnt the process of creating a new project and its builds through the application itself, but by doing so some files are created somewhere and that's what I'm trying to do programmatically:
nsn -ComputerName localhost -port 81 -Credential Get-Credential
I get this error :
nsn : [localhost] Connecting to remote server localhost failed with
the following error message: The WinRM client cannot process the
request. It cannot determine the content type of the HTTP response
from the destination computer. The content type is absent or invalid.
For more information, see the about_Remote_Troubleshooting Help
topic.At line:1 char: 1
+ nsn -ComputerName localhost -Port 81 -Credential Get-Credential
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (System.Manageme....RemoteRunspace:RemoteRunspace) [New-PSSession],
PSRemotingTransportE xception
+ FullyQualifiedErrorId : -2144108297,PSSessionOpenFailed
I also tried in vain set-location http://localhost:81 but got the error saying the path is not a drive (knew it already).
even though the context of what you're trying to do is lacking, you should be able to just use "http://localhost:81" as your url vs an actual web address. PSSession's wouldn't apply here, since you're (likely) not remoting (completely unable to tell though due to lack of details)
edit: thanks for updating your answer. I haven't used TeamCity before, but I'm pretty familiar with Git and TFS, and neither of those would have you connect over WinRM. Also, you wouldn't be able to connect over WinRM to your localhost, as that negates the purpose of Windows Remote Management. If you know what commands you are trying to run after entering the New-PSSession (nsn), just run those and skip starting the PSSession.
I am pretty sure the only commands you'd need to do with TeamCity are git or git-like, which would be outside of Powershell. Otherwise, you'd be going through some sort of API call over http/https and not through WinRM. If you're trying to manage the server that TeamCity is on, that's a different story that brings me back to my point about not needing WinRM because you don't need to remotely manage a server that you're already on, you just manage it directly.

PowerShell remoting using a remote local account on a computer on the same domain

I've made a app in C# that remotly updates the hosts file of the computers on our domain using powershell remoting. It works great but entry level IT Support position in our company do not have their domain accounts part of the admin group on our workstations. They can however use a local admin account. I'm trying to add a 'Connect using a different account' feature but quickly ran into some hurdles. I've fixed all of them but one:
I cannot get it to authenticate using a remote local account and all of my Googling hasn't yielded any solutions.
Here's the code I'm using to update the hosts file:
psInstance.AddScript("Invoke-Command -ComputerName " + computerName + " -ScriptBlock { \"" +
hostsTextBox.Text.Replace("\"", "`\"") + "\" | Out-File c:\\windows\\system32\\drivers\\etc\\hosts }" +
(differentCredentialsCheckbox.Checked ? "-Credential \"" + computerName + "\\\" -Authentication Negotiate " : ""));
When using different credentials, it fails with the following message:
[COMPUTERNAME] Connecting to remote server COMPUTERNAME failed with the following
error message : WinRM cannot process the request. The following error with error code
0x8009030e occurred while using Negotiate authentication: A specified logon session
does not exist. It may already have been terminated. This can occur if the provided
credentials are not valid on the target server, or if the server identity could not
be verified. If you trust the server identity, add the server name to the
TrustedHosts list, and then retry the request. Use winrm.cmd to view or edit the
TrustedHosts list. Note that computers in the TrustedHosts list might not be
authenticated. For more information about how to edit the TrustedHosts list, run the
following command: winrm help config. For more information, see the
about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (COMPUTERNAME:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : 1312,PSSessionStateBroken
Now if I understand correctly using a remote local account only works if:
The connection is made using HTTPS however that brings it own set of problems. A certificate would need to be created for each computer the tool is meant to be used and install on our 500+ workstations. Also, the process need to be started over if the technician gets a new computer (which shouldn't happen often but has a non-zero possibility)
The computers trusts each other using TrustedHosts but that too has the same problems as #1.
Note: We are the local IT group working at one of the branch of a multinational company, we do not have access to GPO so we do not have any easy ways of pushing certificates to our workstations. Also, each groups within our branch are secluded on their own VLAN.
Does anyone can think of a way to achieve what I'm trying to do?
Actually it's not that hard.
I think you read the manual wrong ;-) I can make a similar case work just fine by adding the remote server to the trusted hosts on the client server (the one initiating the session).
You need EITHER https or trusted host. Not both.
To update trusted hosts (overwrites whatever might be in there):
winrm s winrm/config/client '#{TrustedHosts="ServerName"}' so you might want to do some string manipulation to add to any existing hosts.
If you get an error in that command, ensure a winrm quickconfig first.
My invovation is simply:
Invoke-Command -ComputerName $rmServerName -Credential $rmCred -ScriptBlock $block -ArgumentList $destName -ErrorAction:Stop
This works for me across domains with no SSL setup.
You're correct about needing HTTPS and TrustedHosts. One thing you might not be aware of is that the computers probably already have certificates. If there is an enterprise CA set up in the domain, the computers are probably set up for autoenrollment.
Constrained Endpoints
Something else that may work is to create a special Powershell endpoint for this task, and give it a RunAsCredential of the local user. I am not 100% on whether it works with a local user but I think it could.
If you're not familiar, the steps are to use New-PSSessionConfigurationFile to create the session definition, then use RegisterPSSessionConfiguration with that file to register it on the local machine. In the latter call, you can supply a -RunAsCredential and the powershell session will run under those credentials. You can delegate access to non-administrative (domain) users to access this endpoint (use the -ShowSecurityDescriptorUI parameter of Register-PSSSessionConfiguration to make this easy).
This won't require HTTPS nor TrustedHosts.
I have done this before and it definitely works, I just don't know for sure if you can use a local admin for the RunAs user.
If not, you can use a domain account with local admin rights; the helpdesk people won't be authenticating directly as that user so they won't need its credentials.
References
New-PSSessionConfigurationFile
Register-PSSessionConfiguration
We use custom credentials for one of our tools and rather than using custom credentials in PowerShell we launch a new process using NetOnly credentials.
We do this in C# however you can also just run the application using the runas /netonly /user:localadmin and you're prompted for a password.