PSRemotingTransportException in creating a Remote PowerShell Runspace in C# - c#

I have the following code to connect to a remote computer:
var credential = new PSCredential(username, securePassword);
var rri = new WSManConnectionInfo(new Uri(uri), schema, credential)
{
AuthenticationMechanism = AuthenticationMechanism.Kerberos,
ProxyAuthentication = AuthenticationMechanism.Negotiate
};
var remoteRunspace = RunspaceFactory.CreateRunspace(rri);
remoteRunspace.Open();
But it's throwing the following exception:
System.Management.Automation.Remoting.PSRemotingTransportException was unhandled by user code
HResult=-2146233087
Message=Connecting to remote server sw-spdev02 failed with the following error message : WinRM cannot process the request. The following error with errorcode 0x80090311 occurred while using Kerberos authentication: There are currently no logon servers available to service the logon request.
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.
The equivalent code in PowerShell ISE is working properly:
$cred = new-object -typename System.Management.Automation.PSCredential `-argumentlist 'domain\user', ('password' | ConvertTo-SecureString -AsPlainText -Force)
$session = New-PSSession http://servername -Credential $cred
As a hint, I was getting this exception in ISE too before I ran this script:
Set-Item -Path WSMan:\localhost\Client\TrustedHosts -Value http://servername
Another point is that, the computer which the script is running on, and the remote computer are in different domains.
Why am I getting this exception in C# and not in PowerShell ISE?

I don't know why! But I changed the code to this and it worked. I've just set the port number to 5985:
var rri = new WSManConnectionInfo(false, "sw-spdev02.mahanair.aero", 5985, "wsman",
"http://schemas.microsoft.com/powershell/Microsoft.PowerShell", credential)
{
ProxyAuthentication = AuthenticationMechanism.Negotiate,
AuthenticationMechanism = AuthenticationMechanism.Default,
};
Also I've used Username#Domain style instead of Domain\Username as #Donal said in the comments.

I you get that kind of an error when trying to initiate a remote connection and execute commands , most probably you are using the wrong credentials . You might want to cross check your credentials , use the credentials that you use to login to the machine.
Notice that am using the same credentials from the environment variables here:
Sometimes using the environment variables might mislead if your using your Microsoft account to login to your machine. Use your Microsoft credentials instead.
Now it works if you use the same credentials as your Microsoft Account.

Related

Connect to Postgres DB in AWS using IAM Authentication with SSL

I have an RDS instance running Postgres which has IAM Authentication enabled. I can successfully connect using an IAM token via powershell, but I'm having trouble with certificates when trying to connect using the Npgsql library with C# (targeting .Net Core 3.1) from Visual Studio 2019 Version 16.8.5 (on .Net Framework 4.8).
Note, I've been referencing this AWS page, which gives download links for the certificates.
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html
I've also been referencing this page to guide me through getting this set up.
https://aws.amazon.com/premiumsupport/knowledge-center/rds-postgresql-connect-using-iam/
I can connect with PowerShell, using:
$ENV:RDSHOST="my-postgres-instance.eu-west-1.rds.amazonaws.com"
$ENV:PGPASSWORD="$(aws rds generate-db-auth-token --hostname $ENV:RDSHOST --port 5432 --region eu-west-1 --username my_db_user)"
psql -h $ENV:RDSHOST -p 5432 "sslmode=verify-full sslrootcert=rds-ca-2019-root.pem dbname=my_db user=my_db_user password=$ENV:PGPASSWORD"
However when I try to open a connection with C# using the Npgsql library with the code below, I get an exception:
var host = "my-postgres-instance.eu-west-1.rds.amazonaws.com";
var port = 5432;
var user = "my_db_user";
var token = RDSAuthTokenGenerator.GenerateAuthToken(RegionEndpoint.EUWest1, host, port, user);
var builder = new NpgsqlConnectionStringBuilder
{
Host = host,
Port = port,
Database = "my_db",
Username = user,
Password = token,
SslMode = SslMode.Require,
RootCertificate = #"C:\Path\To\Cert\rds-combined-ca-bundle.pem",
};
using (var conn = new NpgsqlConnection(builder.ConnectionString))
{
conn.Open();
}
Npgsql.NpgsqlException: 'Exception while performing SSL handshake
AuthenticationException: The remote certificate is invalid according to the validation procedure.
It's worth noting that I can connect setting TrustServerCertificate = true, however as I understand it, this is masking the problem and reducing security, and is not advisable.
The AWS page linked above mentions:
If your application is on Microsoft Windows and requires a PKCS7 file, you can download the PKCS7 certificate bundle. This bundle contains both the intermediate and root certificates at https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.p7b.
I've tried specifying this p7b file as the NpgsqlConnectionStringBuilder.ClientCertificate, but this causes a different exception when opening the connection:
Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException: 'Cannot find the original signer.'
Anyone able to help me understand how to connect? It's worth noting that I'm not very familiar with detting up SSL connections or dealing with certificates, so bear that in mind.

WinRM client sent a request to an HTTP server, while opening Runspace in WinRM

I am trying to access the Remote system service details using powershell System.Management.Automation dll.
When i am executing the below code to connect to the remote system I am facing the error:
Code snippet:
string shellUri = "http://schemas.microsoft.com/powershell/Microsoft.PowerShell";
PSCredential remoteCredential = new PSCredential("uname", this.convertToSecureString("password"));
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(new Uri("http://machinename/powershell"), shellUri, remoteCredential);
connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Kerberos;
Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo);
runspace.Open();//Here Exception raised
Error Details:
The WinRM client sent a request to an HTTP server and got a response
saying the requested HTTP URL was not available. This is usually
returned by a HTTP server that does not support the WS-Management
protocol
I had the same issue, the uri that i used and worked is http://machinename/powershell/
I had also similar error message with basic authentification, so using Kerberos is needed in some cases.

TF400324 error, but only when using the TFS API

I've seen a lot of discussion about "TF400324: Team Foundation services are not available from server", but everything I've read relates to DNS or proxies, and reflect being unable to connect to TFS at all, through any channel. My case is different: I cannot reach my TFS server when using the .NET library, but it works fine using Visual Studio's workflow tools, and I can reach the same URL just fine in a browser.
Zee code, it is here:
private TfsConfigurationServer _server;
...
Uri url = new Uri(serverName + rootFolder);
var creds1 = new NetworkCredential(username, password, Environment.UserDomainName);
var creds2 = new BasicAuthCredential(creds1);
var creds3 = new TfsClientCredentials(creds2) { AllowInteractive = false };
_server = new TfsConfigurationServer(url, creds3);
// Throws Microsoft.TeamFoundation.TeamFoundationServiceUnavailableException
_server.Authenticate();
The creds are needlessly elaborate because I've tried various suggested solutions, but I don't think that's relevant; I get the same behavior with any other creds I've tried, or no creds at all.
If I copy the exact URL to a browser, I can authenticate and proceed. Within Visual Studio I can connect to TFS using Source Control Explorer and other tools, without explicitly authenticating. What might the library want handled differently?
Additional detail from the error:
Team Foundation services are not available from server https://tfs.imahufflepuff.com:8080/tfs/Root/Project.
Technical information (for administrator):
The underlying connection was closed: An unexpected error occurred on a send.
---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send.
---> System.IO.IOException: The handshake failed due to an unexpected packet format.
We don't have an in-house TFS admin, otherwise I'd kick this issue over to him. I've tried to use Fiddler to get additional detail, but VS consistently refuses to show up there. I can reach an externally-hosted API while debugging, so I don't think there's a network or proxy problem locking down VS.
Have you tried using TfsTeamProjectCollection class instead of TfsConfigurationServer ?
E.g.
Uri url = new Uri(serverName + rootFolder);
var creds = new NetworkCredential(username, password, Environment.UserDomainName);
var server = new TfsTeamProjectCollection(url, creds);
server.Authenticate();
You can also try debugging this issue using Fiddler. You'll have to change VS proxy settings before starting Fiddler:
Either set the registry key reg add hkcu\SOFTWARE\Microsoft\VisualStudio\12.0\TeamFoundation\RequestSettings
/v BypassProxyOnLocal /t REG_SZ /d False
or
Set environment variable TFS_BYPASS_PROXY_ON_LOCAL=0
Seems like an SSL handshake issue at its root, which has nothing to do with the TFS and HTTP protocol and authentication, they sit above SSL. So make sure you have a valid certificate, matching hostname, good validity, accessible CRL where the cert is not revoked, etc. Also check in other browsers or openssl.exe ("openssl.exe s_client -connect servername:8080") for more diagnostic info. You didn't mention but a proxy or an SSL-level certificate authentication could also cause problems, should be easily debuggable by the methods I mentioned above.

PowerShell remoting from a Windows service

I have a Windows service that regulary runs a PowerShell script on a remote computer via WsManConnectionInfo/RunspaceFactory (following the steps from this article: Remotely Executing Commands in PowerShell using C#):
var connectionInfo = new WSManConnectionInfo(false, server, 5985, "/wsman",
"http://schemas.microsoft.com/powershell/Microsoft.PowerShell",
cred)
{
OperationTimeout = 4*60*1000,
OpenTimeout = 1*60*1000
};
using (var runSpace = RunspaceFactory.CreateRunspace(connectionInfo))
{
runSpace.Open();
using (var p = runSpace.CreatePipeline())
{
p.Commands.AddScript(script);
var output = p.Invoke();
...
}
}
Now, if I run the Windows service itself with an Administrator account, all is well. But if i run the service with the LocalSystem account, I get the following exception;
System.Management.Automation.Remoting.PSRemotingTransportException:
Connecting to remote server NOSRVDEV02 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.
at System.Management.Automation.Runspaces.AsyncResult.EndInvoke()
at System.Management.Automation.Runspaces.Internal.RunspacePoolInternal.EndOpen(IAsyncResult asyncResult)
at System.Management.Automation.RemoteRunspace.Open()
...
Note: This has nothing to do with the credentials in WSManConnectionInfo - just the account settings in the service properties "Log On" tab.
I don't want to give the service admin privileges. Any ideas why the LocalSystem user fails to log in?
Additional info:
The remote computer is not a member of a domain.
I have tried to connect both by IP address and hostname (both are listed in the local computer's TrustedHosts).
EDIT: Even more info (summary of the comments):
Local computer: Windows 7 Ultimate 64bit (virtual machine on a Windows 8 box).
Remote computer: Windows Server 2008R2 Datacenter 64bit.
The main reason we don't want to change service user accounts is that this is an update to an old service which is already deployed on many clients (customers).
The service also accesses the Windows registry and the file system on the local computer, so setting the user account to something more restricted, like NetworkService, would just open a different can of worms.
A rather surprising solution to this one: The username in the PSCredential object (cred) needed to be prefixed with the domain-less remote computer's name, e.g. "MYREMOTESERVERNAME\remoteusername" and not just "remoteusername".
I have no idea why the prefix is needed only when connecting with the LocalSystem account though...

PowerShell - New-WebServiceProxy Error: Object moved

I want to use a SharePoint 2010 WebService with PowerShell.
But when I execute my code, a error is thrown.
$a = New-WebServiceProxy $url
New-WebServiceProxy : The request failed with the error message:
-- <head><title>Object moved</title></head> <body><h1>Object
Moved</h1>This object may be found...
Any ideas to solve this problem?
You are getting redirected from the service url. Try it in a browser when you are not authenticated and you'll see what is happening.
You need authenticate your request with SharePoint, or make the service available to anonymous users. Pass default credentials (currently logged in Windows user) as follows. This will work if your SharePoint instane is using Windows authentication.
$a = New-WebServiceProxy -Uri $uri -Namespace myNs -UseDefaultCredential

Categories

Resources