The CruiseControl.Net tfs integration requires a username and password for a user with rather high privileges to be stored in the configuration files. I'm not very fond of that, and have tried to think of ways to have the password stored securely and yet maintain fully automated builds.
Powershell has good support for this with the ConvertTo-SecureStringand ConvertFrom-SecureString commands, and something like this would handle the encryption:
"password-string" | ConvertTo-SecureString -AsPlainText -Force | Out-File pwd.dat
And this could handle decryption:
$user = "mydomain\myuser"
$pwd = Get-Content pwd.dat | ConvertFrom-SecureString
$cred = New-Object System.Management.Automation.PSCredential($user, $pwd)
CruiseControl.Net has a <powershell> task that can be used for running powershell scripts, but I'm unsure whether this can be made to return anyhting. I'm wondering if anyone has any ideas on how to implement secure passwords with CruiseControl.Net? Using Powershell isn't necessary, I'm just figuring it would be neat.
Found a workaround at least: if you omit the <user>,<password> and <domain> parameters, CruiseControl will use the credentials for the user running the service.
The more general question, whether it is possble to catch output remains to be tested. I guess it could be possible to set an environment variable using [system]::SetEnvironmentVariable(name,value), but I haven't tested this.
Related
I am having challenge with one of my Powershell scripts. The idea is to run a tool from a client, which will kill some processes using the PID. Proof of concept works - ps1 script is converted to exe (PS2GUI) and the tool is successfully killing the PID of the user on the server.
$credentials = New-Object System.Management.Automation.PsCredential("domain\user",$password)
$scriptBlockSQL = {
sqlplus.exe command
}
Invoke-Command -ComputerName "server" -Credential $credentials -scriptBlock $scriptBlockSQL
However I have a bit of a problem, because I currently store the password in the script as clear text which is very unsafe - since the .exe can be decompiled in less than a few seconds.
I have tried the ConvertTo-SecureString with the encrypted string, however this ties it with the user account & pc - which is not an option. The usage of the Key file is also not an option.
Do you have any suggestion how to make the script safer & usable? Or any other solution which will work in the same way?
Thanks!
Well, when you are encrypting password with a SecureString then you have to define the password somewhere in the code or in another file. So this is not a good idea. Then you have to look for a way to protect script source code in an efficient way.
PS2GUI will encrypt your source code in a reversible encryption, that means when the script is ran by powershell, the engine will decrypt the code. It is also weak because of using symmetric key algorithm.
Powershell scripts are also encrypted in Base64 format, and PS2GUI does the quite same like thing.
The best way I think now is to prompt the user for credentials. Like this:
$password = Read-Host "Enter password" -AsSecureString
Afternoon folks,
I've got a quick question. I'm making a script to make local user accounts based off a csv file. I have it all working no problem using the New-LocalUser command. What I am curious about is there a parameter string I can add or anything to have it so the user Has to change the password upon first login?
I've looked through https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.localaccounts/new-localuser?view=powershell-5.1 I just was wondering if there was something I've missed.
You haven't. Most of the time, when cmdlets are released, they don't include all functionality for a particular technology (e.g. Get-Service versus Win32_Service). In this case, New-LocalUser, Get-LocalUser, Set-LocalUser are in this boat.
However, in order to achieve what you're after, the WinNT provider has exposed this functionality for a long time:
$u = New-LocalUser -Name test -Password ('123456789' | ConvertTo-SecureString -AsPlainText -Force)
$WinNt = [adsi]"WinNT://localhost/$($u.Name)"
$WinNt.PasswordExpired = 1
$WinNt.SetInfo()
I'm using the following to create the password file:
$path = "C:\Users\USER\Desktop"
$passwd = Read-Host "enter desired password" -AsSecureString
$encpwd = ConvertFrom-SecureString $passwd
$encpwd > $path\filename.bin
Then calling the file with:
# define path to store password and input password
$path = "C:\Users\USER\Desktop"
# get the encrypted password from the path
$encpwd = Get-Content $path\filename.bin
# convert file to secure string
$passwd = ConvertTo-SecureString $encpwd
# define needed credential
$cred = new-object System.Management.Automation.PSCredential 'WIN-SERVER\AdminForQB',$passwd
# go to DVD drive launch setup.exe as user with privileges to launch the program with no user input required
Set-Location "C:\Program Files (x86)\Intuit\QuickBooks 2017\"
Start-Process PowerShell -windowstyle hidden -Cred $cred -ArgumentList .\QBW32PremierAccountant.exe
My goal is be able to run QB2017 with admin privs without giving the user admin privs. The issue I am having is that I have to generate the password file on each user or I get the following error if a user trys to use one generated from another user:
Key not valid for use in specified state.
Is there a way to use this method without generating a key per user?
When you use ConvertTo-SecureString and ConvertFrom-SecureString without a Key or SecureKey, Powershell will use Windows Data Protection API (DPAPI) to encrypt/decrypt your strings. This means that it will only work for the same user on the same computer.
When you use a Key/SecureKey, the Advanced Encryption Standard (AES) encryption algorithm is used. You are able to use the stored credential from any machine with any user so long as you know the AES Key that was used.
More info on this topic (with example code)
Note: This is only Security through obscurity, which isn't good practice. If you store the Key on the same computer as the encrypted password, it's not much more secure than plain text passwords!
PowerShell is the wrong solution for this.
To fix this you should give them read/write access to the folders and registry key QB2017 needs access to. If you still have issues, create a Shim using Microsoft's Application Compatibly Toolkit.
https://deployhappiness.com/fixing-applications-that-require-administrator-rights/
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.
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.