Unable to contact server when I SSH into Powershell using an RSA key - powershell

I am working on a script that logs into a VM connected to my AD to perform some administrative functions. The script will be triggered by an application running on a Linux host. I've installed PowerShell Core and the Windows-Compatibility PowerShell module to allow me to log in via SSH. I can log in successfully and run the my script if I use a password, but if I log in using an RSA key, I get this error when I import AD:
Unable to contact the server. This may be because this server does not
exist, it is currently down, or it does not have the Active Directory
Web Services running.
CategoryInfo : ResourceUnavailable: (:) [Get-ADComputer], ADServerDownException
FullyQualifiedErrorId : ActiveDirectoryServer:0,Microsoft.ActiveDirectory.Management.Commands.GetADComputer
PSComputerName : localhost
The script on the Linux host looks something like this:
#!/bin/bash
ssh ad\\ad-user#windows-host-ip \
-o IdentitiesOnly=yes \
-i ./id_rsa \
"C:\\pwsh\\pwsh.exe -c C:\Users\ad-user\Scripts\ad-management-script.ps1"
And the ad-management-script.ps1 looks something like this:
Import-WinModule ActiveDirectory
Get-ADUser -Identity ad-user
Like I said before: This runs perfectly if I leave the key off and enter a password, but it hits the error I mentioned above if I use the key.
Other notes: Regardless of which method I use to log in, I get these values from the $env:
> $env:username
ad-user
> $env:userdomain
ad
Thanks in advance for any guidance.

As per brief googling looks like people are getting similar issues with ActiveDirectory module while remoting to Windows machine. Not sure suggested workarounds are applicable to your case though. However there are alternatives for using this module. Try options below and see if any of it works.
1. In Powershell (not core):
$user = "someuser"
$searchByUser = "(&(objectCategory=person)(objectClass=organizationalPerson)(samaccountname=$user))"
([adsisearcher]$searchByUser).FindOne().Properties
2. DSQUERY (In CMD, no need for powershell)
dsquery * -filter "samaccountname=someuser"
3. NET (in CMD)
net user SOMEUSER /domain

This is known as the double hop problem. We can not use keys which are used for authentication to remote VM , to authenticate AD server too. There are multiple option which you can use, here is the guide
https://learn.microsoft.com/en-us/powershell/scripting/learn/remoting/ps-remoting-second-hop?view=powershell-7.2

Related

Attempting to run Powershell on Remote Computer - Errors

I am wanting to access another windows device on my local network and run powershell commands. In my mind, it would be similar to SSH into a linux box. I would have an open window on my machine, but would be operating within the remote machine so that I can execute composer install or php artisan migrate type commands on the remote machine.
I have followed the instructions from:
https://www.howtogeek.com/117192/how-to-run-powershell-commands-on-remote-computers/
I am attempting to use
Enter-PSSession -ComputerName <RemoteComputerName> -Credential <RemoteUser>
When I run the command, I get a popup with the username populated and asking for a password. I have entered my MS password for the account. (I have changed the password from within Windows to ensure they are synced)
And I get the following error:
Enter-PSSession : Connecting to remote server <REMOTECOMPUTER> 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.
At line:1 char:1
+ Enter-PSSession -ComputerName <REMOTECOMPUTER> -Credential <USER>
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (<REMOTECOMPUTER>:String) [Enter-PSSession], PSRemotingTransportException
+ FullyQualifiedErrorId : CreateRemoteRunspaceFailed
I can't seem to figure out how to do this. And, maybe more importantly, is there a better way/utility to accomplish my goal? The remote computer is hosting WAMP and I just want to be execute development commands remotely so I can move the RemoteComputer into the basement and not have to spin my chair around to type on it.
TIA

Import Module with an different user account

Are you able to import a module through PowerShell with a different user account? I am specifically attempting to import the ActiveDirectory module with a different account to the currently logged in one.
I don't want to go all out for the console though because I am attempting to use the current Outlook process to send an email after the part of the code is done, and if the entire console is elevated it will give a COM error (instance of PowerShell and Outlook are not elevated together).
The SMTP way of sending an email or through Send-Mail won't work as even though I can ping the SMTP server, I get the below error message, which from what I've read is because I am unable to communicate with the SMTP server appropriately?
Exception calling "Send" with "1" argument(s): "Failure sending mail."
At C:\Users\\Desktop\SCRIPT.ps1:64 char:9
+ $SMTP.Send($MSG)
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SmtpException
You can't import a module with a different account as it doesn't work this way. You need to run the individual commands themselves with alternative credentials.
As you mentioned AD I've used Get-ADUser as an example but a lot of powershell commands have a Credential or PSCredential parameter of some kind, check the documentation to find out.
$Credentials = Get-Credential
Get-ADUser JohnSmith -Properties DistinguishedName -Credential $Credentials
This above example will prompt for credentials, but you can also save them in the script instead on entering them every time.
NOTE: Saving credentials in a file isn't secure so be careful what credentials you save and where you store them!
$Username = "DomainUserName"
$Password = "PlainPassword" | ConvertTo-SecureString -AsPlainText -Force
$Credentials = New-Object System.Management.Automation.PSCredential($Username ,$Password)
There are also other ways to save credentials, but that's too much to go into here.
The AD module for powershell is a wrapper around much of the .NET framework's System.DirectoryServices namespace of code.
.NET in turn is wrapped on top of the older COM ADSI component.
Because of this, it is possible to use windows cached credentials to handle the AD work without using the -Credential option.
If you cache a Windows Domain credential prior to running the script, the AD cmdlets will use those cached credentials to authenticate to the DC. Of course, there's no requirement to remove the cached credential...but realize it's static. if the password changes in the domain, you need to re-cache the cred.
The management of domain creds can be done by command line as well using the cmdkey.exe program that is present since Win7. Using this command line tool, you could set the windows credential just before you run your script, then remove the credential after.
Note that the use of the cached creds is based solely on the server name that the cmdlet will attempt to communicate. If you are not specifying a DC in your cmdlet calls, then it will use the %logonserver% environment variable.
The critical piece then is that the servername used by ADSI must match exactly in the credential cache. If the short name (server01) is used, then that must be in the cache. If the full dns name is used (server01.domain.com), then that must be in the cache. If you feel that your script may change to another server, then that server must be in the cache.

Powershell remoting - cannot execute an exe as another user

I've a commandline program (c#) that encrypts config files based on machine key.
A powershell script copies the build to a Target Server, modifies configs accordingly and installs windows services.
All the windows services run as local system account (standard user, non-admin) - let's call this account "locuser".
The Target Server is a Win 2012 R2 Server. All of the above is achieved by PS remoting from the Build Server to this Target server.
Now, I need to run the encrypt commandline program as "locuser", so that the program can use the account specific key to do the encryption.
I know that this can be easily achieved by calling Start-Process cmdlet with -Credentials parameter. Well, here's the catch, the above works fine, if I remote in (RDP) to the Target Server and then run the Start-Process .... -Credential $cred from a Powershell Console.
However, I need this to be working while I remote-in (using my scripts) to the TargetServer whilst deploying. When I remote-in to the TargetServer I use credentials that has Admin privileges.
I've tried the following
I've granted "locuser" both "Full Control" and "Invoke (Execute)" permissions by using the Set-PSSessionConfiguration -Name Microsoft.PowerShell -ShowSecurityDescriptorUI command. I've run this command for both Microsoft.Powershell and Microsoft.Powershell32 - Still get Access Denied
I've edited the "Local Security Policy"->"Local Policies"->"User Rights Assignment"->Impersonate a client after authentication - and added both the Admin account (that I login with) and the "locuser" account - Still get Access Denied
I've also granted locuser admin rights - Still get Access Denied
I'm pretty sure, there is some configuration on the PS Remoting Side of things that I'm missing out but can't figure out what - because all Powershell throws me is a Access Denied error (see screenshot) with little to no useful information to troubleshoot further.
Also, checked Event logs for any traces but to no avail.
You've fallen prey to the dreaded Double Hop. Basically you're authenticating from computer A to computer B, then trying to authenticate again from computer B to computer C (which also happens to be B in this case).
If at all possible, you would be better off ending the session and starting a new one with the locuser credentials, then just calling Start-Process. Another, more messy approach is to use schtasks.
I can tell you how to do it in the same session but it's a bit messy and very complicated, and should only be a last resort:
On the originating server (Build Server):
Run the command Enable-WSManCredSSP -Role Client -Delegate [name] where [name] is an IP or DNS address / range including any target servers (eg "192.168.1.*")
Open GPEdit.msc, navigate to Computer Configuration\Administrative Templates\System\Credentials Delegation and check that the rules Allow delegating fresh credentials and Allow delegating fresh credentials with NTLM... are enabled and include [name]
On the Target Server:
Run the command Enable-WSManCredSSP -Role Server
Running the command:
Invoke-Command [targetserver] [-Credential $cred] -Scriptblock {
## do stuff
Invoke-Command . -Credential $locusercred -Authentication Credssp -ScriptBlock {
Start-Process -FilePath $sc #etc
}
}
Some things to be aware of:
Firstly I used this setup to create a local session, then remote from there (so A-A-B instead of A-B-B) so the Group Policy stuff might be in the wrong place but pretty sure it's right.
Secondly I found that credentials are a pain to get working in sessions (in this case $locusercred). I did get it going natively but weirdly it suddenly couldn't decrypt the securestring. I ended up saving a securestring with a defined key to the registry so it can always be decrypted from any account, you may need to come up with your own solution there.
All this stuff is explained in the free eBook "The Secrets of PowerShell Remoting", if you go for the double-hop approach I recommend giving it a read.

How to Specify the Password to repadmin.exe via Remote PowerShell Session

I have some issues with repadmin.exe utility
I have the following setup:
Windows Server 2012R2 with ADDS installed running inside of VMWare VM
Windows 8.1 Pro (host for VMware, my home desktop). My host is NOT a part of the domain
I do the following:
Open PowerShell ISE on my Windows 8.1 and establish remote connection to my DC (PowerShell ISE -> File -> New Remote PowerShell Tab)
Once I`m connected remotely to DC I run the following command
repadmin.exe /syncall
and get the following error:
CALLBACK MESSAGE: Error contacting server ad864315-1f78-4266-a7c2-2d6f9cde2f15._msdcs.arvo.local (network error): 5 (0x5):
Access is denied.
CALLBACK MESSAGE: Error contacting server a5904e4b-dff2-4b75-b856-45593a48d84e._msdcs.arvo.local (network error): 5 (0x5):
Access is denied.
SyncAll exited with fatal Win32 error: 8440 (0x20f8):
The naming context specified for this replication operation is invalid.
I found here http://technet.microsoft.com/de-de/library/cc811552%28v=ws.10%29.aspx that is is possible to specify username and password for repadmin using /u: and /pw: keys. Besides it is possible to pass the password using 2 methods - either specify it explicitly in command line or put * (asterisks) and I will be prompted to enter the password. The second option is more preferable.
So I can do ether this way (specify the password in command line):
repadmin.exe /u:domain_name\user_name /pw:p#ssw0rd /syncall
or use asterisks and enter password after this command:
repadmin.exe /u:domain_name\user_name /pw:* /syncall
Asterisks works locally in PowerShell on the server, but if I run it using Remote PowerShell Session, I get the following error:
repadmin : Password: Failed to query the console mode.
+ CategoryInfo : NotSpecified: (Password: Faile...e console mode.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Is there any workaround? I would not specify the password clearly in command line as it is not secure.
Thanks!
You might try something like this inside the remote PowerShell session:
$MyCreds = Get-Credential
Start-Process -FilePath repadmin.exe -ArgumentList "/syncall" -Credential $MyCreds
That way, you could leverage the security of PowerShell's credential management and just run the process under an account that has access to perform the replication.

Powershell - Invoke command access denied while not running under domain admin account

I'm using a script to create a folder on a remote server which is a filew server and a RODC.
When I run the script from a domain admin user the command complet successfuly. When I run with an account that is on the group that can administer the RODC I got an access denied.
$remotefolder = [scriptblock]::create("New-Item -Path d:\testfolder -type directory -Force ")
Invoke-Command -ComputerName server1 -ScriptBlock $remotefolder
I get this error:
[server1] Connecting to remote server server1 failed with the following error message : Access is denied.
For more information, see the about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (server1:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : AccessDenied,PSSessionStateBroken
As it's an RODC there's no local groups that I can add my users that need to run this script.
Is anybody know how I can stop getting this accessdenied ?
Update 12/12:
I tried the same script block on a domain member server only and I don't get the access denied message, the folder is created as it should. Any toughs on how I can get this script block running on a RODC without using a Domain admin user ?
You should probably read up on PSSessionConfiguration before you do this, so you understand the implications, starting with
help about_Session_Configurations
First, create a domain group called 'RODC PowerShell Users'. Put yourself in it, wait for replication, log off and on again. Check that you're in this group.
Second, from an elevated shell on the RODC, run this:
Set-PSSessionConfiguration microsoft.powershell -ShowSecurityDescriptorUI
(After the first, time you'll probably want to use -Force but it's useful to see what it's doing.) Hit Y when asked to confirm.
After a few seconds it will display the Permissions UI for http://schemas.microsoft.com/powershell/microsoft.powershell
Click Add, enter your group name in the dialog that appears, and click OK.
In the "Permissions for RODC PowerShell Remoting Access" box, start with Read and Execute. (You may need Write or Full Control, depending on what you want to do.)
Click OK.
Then enter Y in the PowerShell window to confirm you want to restart WinRM.
From your remote box, assuming you've already set up remoting on the RODC, you should now be able to run:
Invoke-Command -ComputerName server1 { $env:computername }