Trust relationship auto fix script - powershell

i am trying to come up with a script to automate the fix for the common issue in domain environment "the trust relationship error " for my help-desk employee , where they can just run the script with required variable
options : using power-shell or PsExec and should accept user input for naive user .
looking at powershell a simple line may fix the issue after google research : " Test-COmputerSecureChannel -Repair " which does not require reboot as well
challenges in powershell per my simple knowledge ( remote command execution should be enabled in remote machine which is not an option
> PsExec not available by default windows 7 / citrix employee
computer name : SAWD456335355 ( should be variable - user input )
local admin : Administrator
local password: variable differ from computer to computer ( should be user input as well accept special character )
=================================
Privilege admin level 1 account for pop up
while trying to change the local computer using team viewer a pop up will ask for domain credentials for instance :
user name would be sth like : admingroup1
password for privlege admin : password#123 < for example

There are three ways you could fix this.
What you are actually asking for, repair the secure channel. You will most likely need a local admin account (local because the trust relationship is broken) and a combination of Psexec and PowerShell remoting.
<# Get Help desk operator input#>
$Computer = Read-Host "Enter Computer name"
$AdminAccount = Read-Host "Enter local Admin Account"
$SecurePassword = Read-Host "Enter local Admin Password" -AsSecureString
<# Create Plain text password object and Credential Object#>
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)
$UnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $AdminAccount, $SecurePassword
<#Enable PS Remoting#>
Psexec.exe \$Computer -u $AdminAccount -p $UnsecurePassword -h -d powershell.exe "enable-psremoting -force"
<# Repair secure Channel#>
Invoke-Command -ComputerName $Computer -Credential $Credential -ScriptBlock {
Test-ComputerSecureChannel -Repair
}
Set the domain to NOT reset domain computer accounts. This is probably not recommended in most environments.
In my environment I found the best solution was to prevent automatic system restore (probably after a power outage or similar) that is older than the computer password as discussed here:
https://support.microsoft.com/en-us/kb/295049
My solution was to run a scheduled task to delete system restore points that are older than the current computer password.
Get-ComputerRestorePoint |`
Where {$_.ConvertToDateTime($_.CreationTime) -lt $PasswordLastSet} | `
Delete-ComputerRestorePoints
If no system restore points are left the script creates a new one.
A detailed write up can be found here:
http://blog.buktenica.com/issues-with-domain-membership-after-system-restore/

Related

Running Command as Administrator from a SYSTEM Process

So I need to clear a user's run dialog history which I can do perfectly fine with "reg delete HKEY_CURRENT_USER\Software\Windows etc..." from an elevated powershell window on the logged in user's machine, but what I'm looking to do is that same command but from a SYSTEM powershell process. I have already used psexec to create a powershell window which runs as SYSTEM, but because you can't just use HKEY_CURRENT_USER as SYSTEM with the same results, I am finding it quite difficult. If I could just run that command but as username\Administrator then I wouldn't have this problem.
Also to note, if I can somehow grab the username of the logged on user (from SYSTEM still) in one line in plain text (with no other output in sight), then I can store the username in a variable and convert that to an SID and use HKEY_USERS instead.
P.S. Don't ask why I'm running powershell as SYSTEM, I know what I'm doing :D
you can use get-process under the system context powershell and filter where explorer.exe process is running, get the account it is running under then use to convert to SID and go through the registry.
something like this assuming only 1 explorer.exe process is running which is the norm on windows client OS.
$proc = Get-CimInstance Win32_Process -Filter "name = 'explorer.exe'"
$owner = Invoke-CimMethod -InputObject $proc -MethodName GetOwner
$username = $owner.user
$username will contain the user, $owner will also contain domain and a few other things.
to convert to sid
$objUser = New-Object System.Security.Principal.NTAccount($owner.Domain, $owner.User)
$strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
$strSID.Value

Prevent PowerShell script from being read

I have the below PowerShell script (myscript.ps1) in which I ask for username and password. Depending on the username and password it copies a file to a certain destination.
$credentials = Get-Credential
if ($credentials.Username -eq "user1" -And $credentials.GetNetworkCredential().password -eq "pass1")
{ Copy-Item "test1.pdf" "\test\test1.pdf"; }
else
{ Copy-Item "test2.pdf" "\test\test2.pdf"; }
Requirement: I want to make this file protected so no one can edit it and see the username and password.
PS2EXE
I found a solution found here which converts the PowerShell script to an .exe file. When I originally run the script using PowerShell a dialog box appears allowing me to enter the username and password:
After the .exe is generated and when I run it the credentials dialog box no longer appears. Instead, the console appears saying "Credential:"
I don't know why? I want the credentials form to still appear when running the exe. Any thoughts please?
Q: Why does the EXE prompt with "Credential"?
This isn't an answer to the real question, and is based on guessing/supposition about PS2EXE, but I hope it is useful to clear up some confusion.
Having looked briefly at the PS2EXE page linked above, it seems that this utility encodes the script in Base64 and bundles it with a lightweight (?) custom PowerShell host. When run, I suppose the EXE starts the host, decodes the script and runs it.
The problem is that the Get-Credential cmdlet is running within a PS host that probably can't interact with the desktop. That is, it can't put up the GUI prompt for credentials. It therefore needs to prompt for the Credential property on the command line, explaining why you see that behaviour.
Workaround with Read-Host?
Instead of trying to use Get-Credential to prompt for username and password, you could embrace what PS2EXE seems to be doing and just use Read-Host:
$UserName = Read-Host "Enter username"
$Password = Read-Host "Enter password" -AsSecureString
$Credentials = New-Object System.Management.Automation.PSCredential $UserName,$Password
if ($credentials.Username -eq "user1" -And $credentials.GetNetworkCredential().password -eq "pass1")
{ ... }
Using -AsSecureString will hide the password on the screen. The $Password variable will be of type System.Security.SecureString, which can be used to create a PSCredential object as shown.
You'd need to test this, but it seems that you're able to read from the shell but not from a GUI prompt.
And just to be clear: none of this is anywhere near best-practice security. If you need authentication/authorization for these activities, step back and look at the problem again.
Workaround with two scripts?
It seems that PS2EXE doesn't support -AsSecureString in the same way that normal PowerShell does, i.e. it doesn't hide the characters. A possible workaround for this would be to collect the username and password from the user in one script and then pass them to a PS2EXE-converted script for processing.
Launch-MyScript.ps1:
$Credentials = Get-Credential
& MyScript.exe $Credentials.Username $Credentials.Password
MyScript.exe (coverted with PS2EXE):
param($Username,$Password)
$Credentials = New-Object System.Management.Automation.PSCredential $Username,$Password
if ($Credentials.Username -eq "user1" -and
$Credentials.GetNetworkCredential().password -eq "pass1")
{
...
}
The user runs Launch-MyScript.ps1 and completes the password prompt. Then the EXE is run automatically with the username and password passed in as arguments. Note that, as shown above, the password is a Secure String. Test this; I'm not using PS2EXE so it's a theoretical solution at the moment.
If you can't pass $Password along the pipeline as a Secure String object, you can convert it to text with ConvertFrom-SecureString in the first script, then conver it back with ConvertTo-SecureString in the second one.
According to this article http://windowsitpro.com/powershell/protect-your-powershell-scripts you should first set ur execution policy to AllSigned by Set-ExecutionPolicy AllSigned, then create a certificate using makecert cmdlet.
Then u can sign single script using Set-AuthenticodeSignature cmdlet or use .pfx File to Sign a Script which appears even safer.
Hope it helps a bit.

Powershell remote access to nanoserver on docker

I have created a W10 VM (guest) running docker, pulled microsoft/nanoserver image and hosted a container of the image.
(tutorial here: https://msdn.microsoft.com/en-us/virtualization/windowscontainers/quick_start/quick_start_windows_10)
Everything runs great, even host can ping the container running under guest W10. But what i cannot do, is to connect a remote powershell to container.
Enter-PSSession -ComputerName "<container ip>" -Credential ~\Administrator
This pops up a dialog asking for user and password. I cannot leave it blank or etc - the result is access denied. Any ideas how to connect or set a password for nanoserver container ?
I've been struggling with this for a few days now. However, think my problem is slightly different though, as I'm trying to do an Enter-PSSession to a windows docker container, but from another machine, not the container host.
In this tutorial (http://dinventive.com/blog/2016/01/30/windows-server-core-hello-container/), the guy makes a nested container PSSession inside a host PSSession.
He uses this command, which is only available in the latest versions of Powershell. (not in v3)
Enter-PSSession -ContainerId "<container ID>"
Get the ID by doing :
Get-Container | fl
You also have to check your Powershell version and make an upgrade if needed.
To check PS version :
$PSVersionTable
And to download Powershell latest version : https://www.microsoft.com/en-us/download/details.aspx?id=50395
When connecting to a PS-Session using a IP address it adds some requirements, You must either have the remote device configured to use ssl or have the IP address listed in your trusted hosts.
The solution is to either try use the host name for the device, I have had great success with this. Or play with the trusted hosts list. In my experience it works consistently if you add trusted list entries on your machine and the remote machine as well. You can also specify:
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*"
This will basically set all machines to be in the trusted hosts list, It has its cons like all machines being trusted but in certain restricted networks its acceptable. Doing this on the host and client machine seems to yield best results.
When specifying -Credentials it expects a credential object, You can craft one before the cmdlet to avoid entering it every time like so:
$secpass = convertto-securestring "Password Here" -asplaintext -force
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "Username Here", $secpass
Enter-PSSession -ComputerName "<container ip>" -Credential $cred
Coding credentials like this in a script is bad practice, You should look in to storing credentials in scripts properly, there are plenty of good resources on it.

How to rejoin domain when trust relationship is lost

I have a number of virtual machines which have snapshots applied by using a PowerShell script. Occasionally, the virtual machines lose their "trust relationship" with the domain. This breaks the script as I can no longer use PowerShell remoting to get into the machines and configure them.
How can I remotely reset the trust relationship of these virtual machines? Perhaps there are possibilities for rejoining the domain that don't involve remoting?
Any alternate solutions to manually rejoining the domain require logging in to the computer and doing this locally. I haven't found anything that can do this otherwise.
So far, I've attempted to put together a script that simply remotes into the box as the local administrator:
$password = ConvertTo-SecureString "password" -AsPlainText -Force
$cred= New-Object System.Management.Automation.PSCredential ("Administrator", $password)
$sesh = new-pssession -computername "theMachine" -credential $cred
At this point, I was hoping to use PowerShell to reset the password or something like that to reset the domain trust relationship. However, this results in an error on the last line: Access is Denied.
I don't think you can use the local administrator account with PowerShell remoting. Is there any other way I can remotely get a virtual machine that has lost its domain trust relationship to rejoin the domain?
Interesting a problem. Would a combination of PSExec and netdom work? I don't have a VM with broken trust relationship, so I can't test the idea.
Anyway, PSExec has parameters -u and -p for username and password. Make sure you know a local administrator account. Passing its credentials to PSExec should provide a remote shell even with broken trust relationship. Netdom.exe or a Powershell script can be used to re-join the computer to the domain.
Another an option would be changing the policy for computer accounts. A GPO that sets "Computer Configuration\Windows Settings\Security Settings\Local Policies\Security Options\Domain member: Maximum machine account password age" to 0 would set the computer account password never to expire. This might rise some security issues, though.
Edit
Use psexec to open a shell session. Like so,
psexec -u computer\administrator -p password \\computer cmd
After you got the shell, try and experiment with netdom commands. Remove the computer from the domain and add it to the domain. Netdom join and netdom remove support credential passing, so supply valid domain account credentials. After you know the exact command syntax, save the values to a script file and launch it with psexec like so,
psexec -u computer\administrator -p password \\computer c:\myScript.cmd

How to run PowerShell script from a computer to untrusted domain?

I have some PowerShell scripts to update data in active directory. Now I want to run these scripts from another domain joined computer, but the user that is currently logged in does not have admin rights to AD to run the scripts. How can I pass the credentials first to connect to domain as administrator and then run the script?
I know about the command get-credentials but I don't want any manual intervention.
There is batch file which runs the script and I want to put the credentials once.
I also don't want to show the password to the logged in user. Is there any possibility we can save the password in encrypted format?
Hope there is trust between the two domains
$Server = 'XXXXXXXXXX'
$username = 'Domain\XXXXXXXXXX'
$password = 'XXXXXXXXXX'
$securepassword = ConvertTo-SecureString $Password -AsPlainText -force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList ($username,$securepassword)
Get-ADComputer -Identity $Server -Credential $cred
You can change the entire script in to exe file using PowerGUI and use credentials to save it from being opened.
or
use the script by Brenton J.W. Blawat for encryption located at http://gallery.technet.microsoft.com/scriptcenter/PowerShell-Script-410ef9df
or
use the simple script mentioned in the below article
http://www.interworks.com/blogs/trhymer/2013/07/08/powershell-how-encrypt-and-store-credentials-securely-use-automation-script
Instead of using a batch file you could write a VBS wrapper and then use the script encoder to turn it into a VBE. The script encoder is technically not supported in Vista or 7 but it still works if you can find it somewhere. The other option would be to put all your code into a .Net EXE. Once it’s compiled it would hide the password from an ordinary user. Someone that knows what they are doing could still extract it so be aware of that. The same goes of an encoded VBE.