I'm writting here because this problem is making me crazy.
I'm coding a script to configure a new windows installation. Due to company rules it must be done in Powershell and no windows policies can be used.
I must create a new user and modify (via registry) a couple of configurations. No issue with those topics. Windows 10 creates the user registry file ntuser.dat once the user is logged in for the first time. My problem is that I wanted to modify the registry without ever logging in this new user. I thought I could start a job or a process in the background as the user to trigger the file generation. But it seems it's not working at all:
$USERNAME = $cfgData.cfg.userSettings.userName
$USERPWD = ConvertTo-SecureString -String $USERNAME -AsPlainText -Force
$PC_USER = $env:COMPUTERNAME + "\" + $USERNAME
$userCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $PC_USER, $USERPWD
$output = Start-Job -ScriptBlock { Get-Process -Name explorer } -Credential $userCreds -Verbose
Wait-Job $output | Out-Null
It looks like I can edit the registry but once I log in for the first time with the user, no changes were made.
Any ideas are welcome! I thought about scheduling a task to be performed once the user logs in for the first time, but I have no idea where to start with if I choose this way of solving this problem.
Thx in advance for your time!
Ben
Just to keep everything posted.
I tried the solution from #Jeff Zeitlin (modify the default user NTUSER.DAT file) and it worked like a charm.
Thank you Jeff!
Ben
Related
I am creating a PowerShell script that a user can just run to edit an entry in registry. My problem is that I cannot figure out how to store local admin username and password in the same script so that the user can just double click the script and run it without having to enter username and password manually.
Here is my code:
$username = "testpc\administrator"
$pasword = get-content C:\Users\test1\documents\testpassword.txt
$credential = new-object -typename system.management.automation.pscredential -argumentlist $username, $password
This does not work at all. Please let me know what I am doing wrong here.
Usually I'd ask for an error, but in this case I'll advise different, just because your approach isn't acceptable.
Don't store passwords unencrpted in script. Never.
Don't store passwords encrypted in scripts, which are meant to be read by someone else, especially not a user with less privileges. Never!
Go, figure other ways to solve your problem. Always!
In this case I see two solutions with the given information:
change the ACL for the registry key that need to be changed by the user
Create a scheduled task which runs as SYSTEM. Make sure the user cannot edit the script.
Actually #vrdse is right.
you can create the script with the KEY as parameter and:
create a scheduled job with the credentials of your user and add the script as task.
give the user the right to execute the job but NOT to edit or to delete
give a shortcut to the scheduled job (or a runner script) to the user and make a how-to document to show him,/her how the parameter should be used.
I use clear text passwords as temporary testing stuff to make sure users CANNOT use my script (so it is exactly the opposite of your action).
You can capture credential during execution:
$cred = get-gredential -message 'This script needs a real admin user'
Enter-PSSession -Credential $cred -ComputerName 127.0.0.127
You can build a credential (do not store privileged user data):
$user = 'SuchAGreatDomainName\IAmLowPrivilegedUserName'
$Password = 'SuperSecretPassEverybodyKnows'
$secpassword = ConvertTo-SecureString $Password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($user, $secpassword)
Invoke-RestMethod -Uri $Uri -Credential $Credential
I have a simple Powershell script (that's being run in a step in Octopus deploy) that I'm trying to run as another user. We need it for future steps (each application on our platform runs as its own user account, and I need to be able to run an arbitrary script as that user during the deployment process).
The problem is that even the simplest script fails with completely unhelpful error messages, such as this:
$secpasswd = ConvertTo-SecureString $OctopusParameters["runAsPassword"] -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ($OctopusParameters["runAsUsername"] , $secpasswd)
$job = Start-Job -scriptblock {
whoami
} -credential $credential
$job | Receive-Job -Wait
Which fails with the message:
The background process reported an error with the following message: .
The Octopus tentacle is running as a domain account with admin privileges on the machine.
I've completely exhausted all avenues of investigation now, but we really need to get this working. I think if we can't run a deployment script as a certain user then we're completely screwed.
Nearly three years later I have the same issue... I tried writing the code to a temporary file and using Start-Process, but couldn't get that to work either.
In the end, I wrote the code to file, and then ran it through the Windows task scheduler.
I was using Save-AzureRmProfile for all my scripts to execute azure requests in parallel. I borrowed this idea from auto login to azure with powershell/
I had to update my systems to latest version (AzureRM > 4) and despite the fact that the AzureRmProfile are now AzureRmContext cmdlets I still cannot use it as before.
Scenario
Open a PS console and execute
Save-AzureRmContext -Profile (Add-AzureRmAccount) -Path myprofile.json
# List my VMs
Get-AzureRmVm
Open a second PS console
Import-AzureRmContext -Path myprofile.json
# List my VMs
Get-AzureRmVm
Get-AzureRmVM : Your Azure credentials have not been set up or have expired, please run Login-AzureRMAccount to set up your Azure credentials.
How can I reuse my profile to be loaded in parallel executions?
There's a bug in the cmdlets. Not much you can do (only downgrade).
Track it here: https://github.com/Azure/azure-powershell/issues/3954
Here are a couple of workarounds.
Simple, in memory workaround, would need to be added whenever you import a context:
$ctx = Import-AzureRmContext -Path <path-to-context>
$ctx.Context.TokenCache.Deserialize($ctx.Context.TokenCache.CacheData)
More complex workaround. This creates a permanent file, TokenCache.dat, which, if present, may allow you to avoid this problem on a machine altogether.
In a new POSH window:
$ctx = Import-AzureRmContext -Path <path-to-saved-context>
$session = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance
$cacheFile = [System.IO.Path]::Combine($session.ProfileDirectory, $session.TokenCacheFile)
if (Test-Path $cacheFile) {
$session.DataStore.CopyFile($cacheFile, ($cacheFile + ".bak"))
}
$session.DataStore.WriteFile( $cacheFile, [System.Security.Cryptography.ProtectedData]::Protect($ctx.Context.TokenCache.CacheData, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser))
$session.TokenCache = New-Object -TypeName Microsoft.Azure.Commands.Common.Authentication.ProtectedFileTokenCache -ArgumentList $cacheFile
[Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext.TokenCache = $session.TokenCache
Note that this problem should be fixed in the next release
As a workaround until the issue is not fixed or I downgrade my PS installation I used
$azureAccountName ="my.email#example.com"
$Password = "12345678"
$azurePassword = ConvertTo-SecureString $Password -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAccountName, $azurePassword)
Then in my parallel ScriptBlock I do a call like this to replace the broken import credentials
Login-AzureRmAccount -Credential $psCred
Not the kind of solutions I'm proud of but... it did the trick.
What I have working is a Powershell script that takes a JSON file to create a new VM; the JSON file contains instructions for the VM to join a domain and run a custom script. Both things do happen, but the script runs as the user workgroup\system and therefore doesn't have access to a network drive.
Does listing the extensions in this order guarantee that the script runs after the domain join is complete (or is it haphazard)?
Is there something I can do to ensure that the script does not run until the domain join is complete? How can I best detect (locally from the new VM) that the domain join is complete? How would you delay the running of the script until a better time (something like a once-off cron job)?
Update: Split question in two, other half is here.
Also, immense thanks to Dewi Jones for more than an hour of interactive support. I'm indebted by being able to give only a single check mark in return.
Get the domain and if the domain is equal to the one you are joining then continue.
$domain = gc env:UserDNSDomain
While ($domain -neq "FQDN")
{
Start-Sleep -seconds 2
}
Otherwise you can call a script using credentials as follows
$username = 'user'
$password = 'password'
$PSArgs = 'Script file name'
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword
Start-Process Powershell.exe -Credential $credential $PSArgs
We have a problem with a Service on a Server. So we decided to write a PS-Script that a "normal" User without Admin privileges can start this Service. I have practiced now 2 Day's on this little Script. I'm a newbie (Apprentice) in PS but im glad that it works when I run it as an Admin. But why the heck not as an User?
I have generated the "Secure" Password as follow:
"P#ssword1" | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-File "C:\Temp\Password.txt"
I took the SecureString and pasted it in my Script that looks like this:
$User = "DOMAIN\USER"
$PwHash = "01000000d08c9ddf0....."
$MyCredential=New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, ($PWHash | ConvertTo-SecureString)
Invoke-Command -ComputerName "MyServer" -ScriptBlock {Get-Service -Name "MyService" | Set-Service -Status Running} -Credential ($MyCredential)
The failure pops up by the $MyCredential row:
ConvertTo-SecureString: Key in specific Status is not valid.
I have nowhere read that for an ConvertTo... cmd are Admin rights needed.
Enable-PSRemoting is active on the specific Server.
Thanks for your time and engagement
Dirty.Stone
IMHO, you're going about this all wrong. This is an example of the kind of task you would use JEA (Just Enough Admin) for. Create a constrained, delegated session on the target server, configured with a function for starting or restarting that service and running under a local account that has permission to control the service, and then grant the non-admin users permission to use that session.