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

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.

Related

Powershell calls another PS1 in loop finishes after first foreach loop run completes

I have 2 Powershell scripts, one which is the primary (ServerInfo.ps1) and a secondary script which is intended to work as a wrapper, launching the first script within a loop that will use different credentials on each loop due to queries being made to different AD Domains/Forests that require different domain creds for each respective domain.
The primary script runs fine when run on its own if I run it manually and locally from a machine in each respective domain, and does as needed (grabbing details from remote machines and exporting to a csv)
The following is the Wrapper script (domain name examples changed for security reasons).
# This is a Wrapper Script for ServerInfo.ps1
$username = Read-Host -Prompt 'Enter User Account to be used - Do not specify domain'
$Password = Read-Host -Prompt 'Input User Password - NOTE must be the same on all domains' -AsSecureString
$domains = "d1.contoso.com","d2.contoso.com","dev.contosodev1.com","test.contosotest1.com"
$Arguments = "-file c:\serverinfo\ServerInfo.ps1", "-ServerType 'DCs'"
ForEach ($domain in $domains) {
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "$domain\$username", $Password
Start-Process powershell.exe -Credential $credential -NoNewWindow -ArgumentList $Arguments -WorkingDirectory 'c:\Serverinfo\' -Wait
}
Specifically this will be used to query Domain Controllers with an elevated permissions account that is identical on each domain, as the account used on member computers does not have Builtin Admin or AD (Domain/Enterprise Admin) level rights on the Domain Controllers. The intention is also to run the scripts from a Domain member, not locally on a DC.
As the primary script (serverinfo.ps1) is over 1000 lines of code, I will simply say that with the wrapper passing the argument "-ServerType DCS", ServerInfo.ps1 initially grabs all Domain Controller names from AD of the respective domain the account belongs to, and performs things such as WMI & Registry queries of each DC, exporting the output to a CSV file.
For the first domain, this runs fine without any issue and the ServerInfo.ps1 script does it job querying every DC in the first domain, but then both PowerShell scripts close/stop running without it continuing to the second domain in the wrapper loop aka, the "foreach ($Domain in $Domains)" loop is not working once the first domain completes.
As I don't see any scripting error in the wrapper, and there is no Exit or other cancellation/Finish command in ServerInfo.Ps1, I am at a loss as to why the wrapper is not working as expected.
For the first domain, this runs fine without any issue and the
ServerInfo.ps1 script does it job querying every DC in the first
domain, but then both PowerShell scripts close/stop running without it
continuing to the second domain in the wrapper loop aka, the "foreach
($Domain in $Domains)" loop is not working once the first domain
completes.
I am pretty sure that your loop works. Just insert a Write-Host "Iteration for domain: $domain" inside that loop and you will see, that it indeed iterates over all domains.
I am more concerned about the way you call that other script. With Start-Process -Credential the process will be executed in the user space of the provided user. In your scenario, this will require any trust relationships between your domains, if you want to run it on any domain computer for all domains. Do you have any?
If not, you have to pass the credentials to the called script in some secure way, so that it can authenticate itself when using remote control cmdlets.

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 Automation - Passing Password after executing a exe file

I working on automating the specific task using powershell and getting error while passing the password. Below is my task. Below are the tasks I need to automate.
Execute exe file (For ex: export.exe)
It will prompt for password twice (Enter your password and Reenter your password)
After Entering our password Twice, It will ask for confirmarion Yes or No: (I need to give 'Yes' or No to continue )
I tried automating the above first two steps. First I get the stored password in a file using the below command
$password = get-content C:\cred.txt | convertto-securestring
Then I tried executing the below commands in script
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $pass
Invoke-Expression "& `"C:\Program Files\XX\XX\bin\export.exe`""
But I dont know how to use the password from the file twice to continue the script. I am new to powershell. Please help me.
I don't think that your application will accept PowerShell's PSCredential object. More likely, you just have to pass plaintext password twice and then Yes.
Try this (assuming that export.exe is console application):
'Password', 'Password', 'Yes' | & 'C:\Program Files\XX\XX\bin\export.exe'
This will send 3 strings, separated by the newline (Enter) to the export.exe's stdin.

Copying from one server to other with credentials

I'm trying to copy a file from one server to another server so that it doesn't ask me to enter my login info and I don't have to store the password blatently in the code. The problem is, it's still coming up with a credential request GUI, even though I give the -Credential parameter. This is how I store the password in a file:
read-host -assecurestring | convertfrom-securestring | out-file C:\secString.txt
Then the code looks like this:
function GetSecureLogin() {
$username = "usa02xxxswg2\20xbackup"
$password = get-content C:\secString.txt | convertto-securestring
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
}
function CopyFileToFolder ([string]$Source, [string]$destination){
Copy-Item "$Source" -Destination "$destination" -Credential $cred #this is where the login info box is coming up but shouldn't be
}
######################start here#####################
$cred = ""
GetSecureLogin
$tempSource = "filename.txt"
$ToLocation = "$ToLoc"
CopyFileToFolder $tempSource $ToLoc
Any ideas? I'm relatively new to PowerShell, so I could be doing something silly. I'm not sure how to tell if $cred is getting back to my Copy function ok or if it's out of scope.
I've looked at these examples but I'm having trouble deciding if I need to do something different because they are specifying the server info and I'm trying to avoid that since I just want to use UNC path like I was doing before. The copying was working fine without login because I was using my Active Directory login to save the task. Now we want to use a locally saved login (where the script is run) and then it needs a different local login when it's trying to access the other server.
copy-item with alt cred,
powershell without prompt for cred,
copy without cred,
copy with alt cred,
cred without password prompt
I'm trying to figure out if returning $cred from my GetSecureLogin function, and assigning it to $cred in the main part of the script will fix the problem where it's asking me for the login info when I do the copy. It looks like my co-worker moved all the directories, so I still have to test this once I figure out where he moved them to.
Looks like I figured it out. I did it like this link. It was a little tricky in that I didn't have to use the directory that came after my sharename, but once I got rid of the subdirectory, it worked.
copy with credentials and New-PSDrive

Creating file in a user context in powershell

I am trying to create a file using powershell in a specific user context. E.g I have a user user01 on my local machine and I want to create a file in its context.
I am doing something like
New-Item c:\file.txt -Credential User01
It works but prompts me for password which I dont want it to. Is there any way I can accomplish this without having it prompt for password ?
The credential parameter on new-item is not actually supported for filesystems, so I'm not sure what you mean by "it works." It does NOT create the file as the passed user. In fact, the filesystem provider will say:
"The provider does not support the use of credentials. Perform the operation again without specifying credentials."
Taking an educated guess, I'd say you're trying to create a file with a different owner. PowerShell cannot do this on its own, so you'll need the following non-trivial script:
http://cosmoskey.blogspot.com/2010/07/setting-owner-on-acl-in-powershell.html
It works by enabling the SeBackup privilege for your security token (but you must already be an administrator.) This allows you to set any arbitrary owner on a file. Normally you can only change owner to administrators or your own account.
Oh, and this script is for powershell 2.0 only.
Rather than use a PowerShell cmdlet or .NET scripting on this one, you might take a look at the Windows utility takeown.exe. However, even it requires you supply the user's password that you're assigning ownership to.
Ok, I do start process in the user context and then create a file. Works like a charm.
Password, FilePath and UserName are passed in as arguments from command line.
$pw = convertto-securestring "$Password" -asplaintext –force
$credential = new-object -typename system.management.automation.pscredential -argumentlist "-default-",$pw
$localArgs = "/c echo>$FilePath"
[System.Diagnostics.Process]::Start("cmd", $localArgs, "$UserName", $credential.Password, "$Computer")
Or just make a call to SUBINACL.EXE? No need for password then.