Create Local User Account & Password (Non Domain Joined Machines)


Userlevel 2
Badge

Would it be possible to create a worklet that would target a group of machines that are not on the domain and inject a username and password for all of the machines. I would then want to run a second worklet that would disable the local admin account on all of these machines.


42 replies

We managed to create a local account using the below


Worklet:


Evaluation code - Exit 1


Remediation code -


$comp = [adsi]‘WinNT://localhost,computer’;

2

$user = $comp.Create(‘User’, ‘tempuser’);

3

$user.SetPassword(‘Password’);

4

$user.SetInfo();

5

$user


Haven’t tried disabling the local admin but assume it would be "Disable-LocalUser -Name “Administrator”

Userlevel 2
Badge

Hi Clive,


Thanks for the help. I’ll give it a try on my test machine and let you know if it owrks.


image001.png


image002.png


image003.png


image004.png


image006.jpg

Userlevel 4

Here are a few reference links on how PowerShell can be used to do both of the processes you mentioned as well:




Userlevel 2
Badge

Thanks David,


image001.png


image002.png


image003.png


image004.png


image006.jpg

Userlevel 4
Badge

Worth noting, I’m working on a similar project and those modules are not available on the 32bit version of PS. Automox runs by default as 32bit. You’ll need to wrap any code around a codeblock that invokes the 64bit version of PS.


$scriptblock = {

[64-bit code]

}

& “$env:SystemRoot\sysnative\WindowsPowerShell\v1.0\powershell.exe” -ExecutionPolicy Bypass -WindowStyle Hidden -NoProfile -NonInteractive -Command $scriptblock

Userlevel 2
Badge

Can you explain what you mean by wrapping the code around a codeblock?

Userlevel 4
Badge

Yeah so basically you’ll write whatever code you wanna run, and put it inside that variable $scriptblock. It’ll take that code and pop open a new powershell env, thats 64bit capable.

Userlevel 2
Badge

I think I understand now. The code needs to be between the brackets and the entire block is added to the worklet correct?

Userlevel 2
Badge

Like this right?


$scriptblock = {

$comp = [adsi]‘WinNT://localhost,computer’;

$user = $comp.Create(‘User’, ‘tempuser’);

$user.SetPassword(‘Password’);

$user.SetInfo();

$user

}

& “$env:SystemRoot\sysnative\WindowsPowerShell\v1.0\powershell.exe” -ExecutionPolicy Bypass -WindowStyle Hidden -NoProfile -NonInteractive -Command $scriptblock

Userlevel 4
Badge

I’m not familiar with that method, heres how we do it, and I’m sure theres a better way too… plaintext passwords are always bad to keep in scripts, but for us – they immediately get LAPS’d, so really small amount of risk here.


$scriptblock = {
$Password = ConvertTo-SecureString "Your-Password" -AsPlainText -Force
New-LocalUser "tempuser" -Password $Password -FullName "tempuser" -AccountNeverExpires
Add-LocalGroupMember -Group "Administrators" -Member "tempuser"
Get-LocalUser Administrator | Disable-LocalUser
gpupdate /force
}
& “$env:SystemRoot\sysnative\WindowsPowerShell\v1.0\powershell.exe” -ExecutionPolicy Bypass -WindowStyle Hidden -NoProfile -NonInteractive -Command $scriptblock

EDIT: Guess I should post evaluation too – Props to Tony from support for helping out on this. This’ll see if the tempuser exists and if the local admin account is disabled. If both of those are true, we pass eval. If either of them are not, we fail and remediate.


$tempuser= (Get-WmiObject -Class Win32_UserAccount -Filter "Name = 'tempuser'").name
$defaultadmin = (Get-WmiObject -Class Win32_UserAccount -Filter "Name = 'administrator'").disabled
if ($tempuser -eq "tempuser" -and $defaultadmin -eq "True")
{
exit 0
}
else
{
exit 1
}
Userlevel 2
Badge

Thank you very much for the help. I’ll let you know how it works out.


image001.png


image002.png


image003.png


image004.png


image006.jpg

Userlevel 2
Badge

Thanks again for the help. Once I get the firewalls opened up I’ll test and let you know the results.

Userlevel 4

@Mrichards, thank you. That is key information to share!

Userlevel 2
Badge

So I tried the worklet today, and got the following error in the log:


2020/08/11 11:45:59 cmd.go:108: Executing command: [“try {\r\n $computername = hostname\r\n} catch {\r\n # hostname cmdlet doesn’t exist\r\n $computername = $env:computername\r\n}\r\nif ([string]::IsNullOrEmpty($computername)) {\r\n $computername = “Unknown Windows”\r\n}\r\n$computername\r” “”]

Userlevel 4

The script block method is helpful when there are 64-bit modules that do not exist in 32-bit powershell. @Mrichards has a suggested evaluation and remediation block posted in the string that provides a good functional example of how to use a scriptblock through the sysnative virtual variable.

This only works as defined when running on a 64-bit OS.

The scriptblock method is not required when using asdi as that is not specifically a powershell module only available in 64-bit powershell, when running commands in a 32-bit environment.

If you get a chance, please take a look at @Mrichards suggestion above and see if that works for you. Please note in his example, the script would create ‘tempuser’ and add it to the local administrators group. Ensure that is your intent if you want to use the script as provided.

Userlevel 2
Badge

I have created a worklet based on rmathews example with the only change of removing the line that disables the local Admin account. I’m going to stop the Automox service on the Windows 7 machine, and then rename the log so I can get a fresh one. I’ll let everyone know the results

.

Userlevel 5

Hey guys, that log snippet isn’t an error, it’s just the command that was being executed at that time. In this case, that is part of a scan, the step that confirms and/or potentially updates the device’s hostname.

Userlevel 2
Badge

I just ran the worklet and here is what the log had to say:


2020/08/11 16:04:10 cmd.go:158: Received execCmd command

2020/08/11 16:04:10 cmd.go:108: Executing command: ["\n$scriptblock = {\n$Password = ConvertTo-SecureString “6%CA$wW\” -AsPlainText -Force\nNew-LocalUser “tempuser” -Password $Password -FullName “tempuser” -AccountNeverExpires \nAdd-LocalGroupMember -Group “Administrators” -Member “tempuser”\ngpupdate /force\n}\n& “$env:SystemRoot\sysnative\WindowsPowerShell\v1.0\powershell.exe” -ExecutionPolicy Bypass -WindowStyle Hidden -NoProfile -NonInteractive -Command $scriptblock" “”]

2020/08/11 16:04:11 cmd_windows.go:147: Command End – elapsed 798.6016ms

2020/08/11 16:04:11 mqclient.go:340: Pushing result to agent.35d15657-d64c-4a1e-b939-14b26ce3601a.resp

2020/08/11 16:04:11 cmd.go:158: Received execCmd command

2020/08/11 16:04:11 cmd.go:108: Executing command: [“trap { $host.ui.WriteErrorLine($_.Exception); exit 90 }\n\n$si = New-Object -ComObject “Microsoft.Update.SystemInfo”\nif($si.RebootRequired) {\n “true”\n}” “”]

2020/08/11 16:04:11 cmd_windows.go:147: Command End – elapsed 571.0024ms

2020/08/11 16:04:12 mqclient.go:340: Pushing result to agent.35d15657-d64c-4a1e-b939-14b26ce3601a.resp

2020/08/11 16:04:12 cmd.go:158: Received execCmd command

2020/08/11 16:04:12 cmd.go:108: Executing command: ["# Define WebRequest parameters\r\n$url = “http://169.254.169.254/latest/meta-data/instance-id”\r\n$wr = [Net.WebRequest]::Create($url)\r\n$wr.Timeout = 3000\r\n# Attempt the WebRequest and take action based on response\r\ntry {\r\n $response = $wr.GetResponse()\r\n $sr = New-Object IO.StreamReader($response.GetResponseStream())\r\n $awsID = $sr.ReadToEnd()\r\n if (($awsID.length -ne 11) -and ($awsID.length -ne 19)) {\r\n Write-Error “Invalid AWS ID: $awsID”\r\n exit 1\r\n }\r\n # Otherwise device is a valid AWS instance. Return the AWS ID to stdOut and exit as success\r\n Write-Output $awsID\r\n exit 0\r\n} catch {\r\n # Failure to get a response is expected if device is non-AWS\r\n exit 0\r\n}\r" “”]

2020/08/11 16:04:12 cmd_windows.go:147: Command End – elapsed 655.6021ms

2020/08/11 16:04:12 mqclient.go:340: Pushing result to agent.35d15657-d64c-4a1e-b939-14b26ce3601a.resp

2020/08/11 16:04:12 cmd.go:158: Received execCmd command

2020/08/11 16:04:12 cmd.go:108: Executing command: ["# Gather OS Details from WMI\n# Fallback to registry if WMI is missing or unavailable\n$os = Get-WmiObject -Class Win32_OperatingSystem -ErrorAction Continue\nif ($os) {\n # Preserves existing formatting expected by back-end\n $caption = $os.Caption.Replace(‘Microsoft Windows ‘,’’).Trim()\n $version = $os.Version \n} else {\n $caption = (Get-ItemProperty -Path HKLM:’\Software\Microsoft\Windows NT\CurrentVersion’ -Name ‘ProductName’).ProductName.Replace("Windows “, “”)\n $version = (Get-ItemProperty -Path HKLM:’\Software\Microsoft\Windows NT\CurrentVersion’ -Name ‘CurrentVersion’).CurrentVersion+’.’+(Get-ItemProperty -Path HKLM:’\Software\Microsoft\Windows NT\CurrentVersion’ -Name ‘CurrentBuildNumber’).CurrentBuildNumber\n}\n$language = $(Get-Culture).Name \n\nWrite-Output “Windowsn$captionn$version`n$language”” “”]

2020/08/11 16:04:13 cmd_windows.go:147: Command End – elapsed 657.2012ms

2020/08/11 16:04:13 mqclient.go:340: Pushing result to agent.35d15657-d64c-4a1e-b939-14b26ce3601a.resp

2020/08/11 16:04:13 cmd.go:158: Received execCmd command

2020/08/11 16:04:13 cmd.go:108: Executing command: [“Exit 1” “”]

2020/08/11 16:04:14 cmd_windows.go:135: runScript: Error in Wait exit status 1

status: 1

stdOut: Omitted

stdErr:

Userlevel 2
Badge

I’ve looked through the logs and I see the syntax below:


2020/08/11 16:04:13 cmd.go:158: Received execCmd command

2020/08/11 16:04:13 cmd.go:108: Executing command: [“Exit 1” “”]

2020/08/11 16:04:14 cmd_windows.go:135: runScript: Error in Wait exit status 1

Userlevel 5

Here’s the bit where the command was executed, there’s no error they’re, so it seems to have run with no errors.


This is the evaluation running on the subsequent scan that follows the execution. Assuming that “Exit 1” is the content of your evaluation block. If so, this looks fine.


2020/08/11 16:04:13 cmd.go:108: Executing command: [“Exit 1” “”]

2020/08/11 16:04:14 cmd_windows.go:135: runScript: Error in Wait exit status 1

status: 1


Sorry, I’m on my phone at the moment, so formatting might be rough.

Userlevel 2
Badge

Thanks for the reply. Do I need to reboot the workstation in order to see the changes? I’m remote to the machine in Computer Management and see a new tempuser created or the local admin account disabled.

Userlevel 2
Badge

So I’ve run the worklet on the machine several times, and according to the logs it looks like its working, but no the tempuser account doesn’t get created and the local Administrator accounts doesn’t get disabled. Below is syntax from the most recent log:


2020/08/11 19:40:24 cmd.go:158: Received execCmd command

2020/08/11 19:40:24 cmd.go:108: Executing command: ["\n$Password = ConvertTo-SecureString “6%CA$wW\” -AsPlainText -Force\nNew-LocalUser “tempuser” -Password $Password -FullName “tempuser” -AccountNeverExpires \nAdd-LocalGroupMember -Group “Administrators” -Member “tempuser”\nGet-LocalUser Administrator | Disable-LocalUser\ngpupdate /force" “”]

2020/08/11 19:40:38 cmd_windows.go:147: Command End – elapsed 13.9364283s

2020/08/11 19:40:38 mqclient.go:340: Pushing result to agent.35d15657-d64c-4a1e-b939-14b26ce3601a.resp

Userlevel 2
Badge

Okay I was able to determine that the machine I was trying to run the script had an old version of powershell that did not recognize the localUser cmdlt. I was able to download and install Win7AndW2K8R2-KB3191566-x64 and it installed successfully. I tested the script by running it locally in powershell ISE and it worked. After cleaning things up and trying to run the same script from AutoMox with no result.

Userlevel 2
Badge

Last note for the night. When I run the worklet I get the following in the activity report:


MFS1-STORE11 CMKTS MFS Server Local Account Creation TEST 2

(Worklet) 2020-08-11 9:05 PM PDT Activity Updating Policy… User Policy update has completed successfully. Computer Policy update has completed successfully.


The message looks great, but still no change on the target machine.

Userlevel 2
Badge

So I have determined that the powershell script works fine. I am able to run the script locally on the machine with no problem.


It appears that AutoMox can’t see the user context when running a worklet. This is according to AutoMox.

Reply