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

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.

1 Like

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”

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

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


Thanks David,

image001.png

image002.png

image003.png

image004.png

image006.jpg

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

1 Like

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

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.

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

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

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
    }
1 Like

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

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

1 Like

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

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” “”]

The script block method is helpful when there are 64-bit modules that do not exist in 32-bit powershell. @rmatthews 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 @rmatthews 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.

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
.

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.

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:

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