Skip to main content

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.

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


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

}


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.


@Mrichards, 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 (istring]::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. @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.


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: m“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: 0"# Define WebRequest parameters\r\n$url = “http://169.254.169.254/latest/meta-data/instance-id”\r\n$wr = 6Net.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: r"# 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: 1“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




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: 1“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.


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.


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: m"\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


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.


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.


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