Tagarchief: powershell

One of the recent security “packs” in the Microsoft ecosystem is LAPS, Local Administrator Password Solution ( It tries to solve one of the ancient issues regarding the local administrator account on a Windows machine. It needs to exists, and it needs to have , preferably, secure and unique password. Yet, in many organizations, the default administrator account is enabled, with the exact same password on every machine…
Result: once you know the password, you’re an admin on every workstation! (latteral movement) 🙂
The idea of LAPS is to randomize each password of each workstation, and store it in the Active Directory as an confidential attribute of the computer object.

LAPS can be configured to manage the local administrator account, .\administrator, or another, configurable and existing, account.


Enter MS14-025.
MS14-025 disables the usage of CPasswords in Group Policy .

This is a good thing!

CPasswords allowed unsuspicious administrators to put plaintext password in publicly-readable group policy xml-files!
(almost plaintext as the passwords are encrypted with a known password).

Here is the password btw (

 4e 99 06 e8  fc b6 6c c9  fa f4 93 10  62 0f fe e8
 f4 96 e8 06  cc 05 79 90  20 9b 09 a4  33 b6 6c 1b

Yet, this also means you cannot create a new account using Group Policy anymore.
Little “forgotten” side-effect…

And there is no real alternative to actually create a local account on a domain member…
(At installation of LAPS clientside-MSI, an argument can be set to actually create a new account…)

One way to solve this is to create a new local user is using a startup script!
The script below was tested on Windows 10, some things did break between 8.1 and 10!
Deploy it using SCCM or GPO startupscripts!

It creates an account and LAPS will change its password on first gpupdate

Note, another point of discussion is the fact whether the .\administrator should be used or not. There are a lot of different opinions here…
For LAPS, some people at Microsoft advise to “just use the .\administrator account, because you know it will always be there”. (note: account is prone to bruteforce attacks as a lockoutpolicy never applies to the rid500)
In other cases (src1, src2, src3), Microsoft advises to disable the .\administrator account, create another administrator account and use that one…
Point is, when you’re not using bitlocker, there is a tool called “Offline Windows Password & Registry Editor” by pogostick which can always enable and reset the .\administrator account’s password.
So, the choice is up to you! My humble opinion is to use another account 🙂 (otherwise I wouldn’t be going through all this trouble to get another one 🙂 )


function create-localaccount ([string]$accountName = "testuser", [string]$Computer = "localhost") {   
   $comp = [ADSI]"WinNT://$Computer"  
   $user = $comp.Create("User", $accountName)  
   $user.SetPassword(([char[]](50..150) + 0..9 | sort {get-random})[0..18] -join '') # set a random password, let it be changed by LAPS afterwards

function get-currentlocaladministrators([string]$Computer = "localhost"){
   $obj_group = [ADSI]"WinNT://$Computer/Administrators,group"
   $members= @($obj_group.psbase.Invoke("Members")) | foreach{([ADSI]$_).InvokeGet("Name")}

function add-localadministrators([string]$accountName = "testuser", [string]$Computer = "localhost"){
   $AdminGroup = [ADSI]"WinNT://$Computer/Administrators,group"
   #$User = [ADSI]"WinNT://$hostname/$accountName,user" #something broke on windows 10
   #$AdminGroup.Add($User.Path) #something broke on windows 10
   $objUser = [ADSI]("WinNT://$accountName")

get-currentlocaladministrators -Computer "localhost"
create-localaccount -Computer "localhost" -accountName "testuser"
add-localadministrators -Computer "localhost" -accountName "testuser"
get-currentlocaladministrators -Computer "localhost"

Some good LAPS references: is pretty awesome for a headless torrent client! It even has a native PowerShell module! But it doesn’t implement everything you want. (runs only in x86 shell, no magnets support, …)

Here a quick (and very dirty) PoSh snippet to add magnets to the download engine using its REST API… (don’t judge me on code quality!)

Accesstoken is the “api key” from the upper right corner, id is whatever you want it to be, and the convertto-json can probably be used as well.. But it was late, and this works :-).

while($magnet = read-host "gimme magnets")
$body = @"
Invoke-RestMethod -Method Post -Uri $url -Header @{ "Authorization" = "Token $accesstoken" } -Body $body -ContentType "application/json"
$body = @"
$res=Invoke-RestMethod -Method Post -Uri $url -Header @{ "Authorization" = "Token $accesstoken" } -Body $body -ContentType "application/json"
$res.result |ft

Get-ScheduledTask | Where State -ne “Disabled” | Get-ScheduledTaskInfo | Select TaskName,TaskPath,LastRunTime, LastTaskResult,NextRunTime,NumberofMissedRuns | Sort-Object lastruntime

task running during screensaver

TaskName : RunFullMemoryDiagnostic
TaskPath : \Microsoft\Windows\MemoryDiagnostic\
LastRunTime : 13/03/2014 11:12:12
LastTaskResult : 2147943467
NextRunTime :
NumberofMissedRuns : 0

TaskName : WinSAT
TaskPath : \Microsoft\Windows\Maintenance\
LastRunTime : 13/03/2014 11:12:12
LastTaskResult : 0
NextRunTime :
NumberofMissedRuns : 0

TaskName : Idle Maintenance
TaskPath : \Microsoft\Windows\TaskScheduler\
LastRunTime : 13/03/2014 11:12:12
LastTaskResult : 0
NextRunTime :
NumberofMissedRuns : 0

TaskName : ProcessMemoryDiagnosticEvents
TaskPath : \Microsoft\Windows\MemoryDiagnostic\
LastRunTime : 13/03/2014 11:12:12
LastTaskResult : 2147946720
NextRunTime :
NumberofMissedRuns : 0

TaskName : Regular Maintenance
TaskPath : \Microsoft\Windows\TaskScheduler\
LastRunTime : 13/03/2014 11:12:12
LastTaskResult : 0
NextRunTime : 13/03/2014 15:21:21
NumberofMissedRuns : 0


Type $profile into a PowerShell Windows, and you’ll get something as C:\Users\username\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 in return.

It’s actually just another ps1-file that gets loaded when you open a powershell command.
This gives the user the possibility to really easy add custom PS-snippets into your environment!
And we all have these pieces of code we use almost daily…

To get started, follow this technet guide.

In the end, you’ll get yourself a notepad file you can edit 🙂

Here some usefull function you can paste into it!
Some functions come directly from David Little (thanks!)

$ProfileRoot = (Split-Path -Parent $MyInvocation.MyCommand.Path)
$env:path += ";$ProfileRoot"

function elevate
$file, [string]$arguments = $args;
$psi = new-object System.Diagnostics.ProcessStartInfo $file;
$psi.Arguments = $arguments;
$psi.Verb = "runas";
$psi.WorkingDirectory = get-location;
function Edit {
[Parameter(Mandatory = $False, ValueFromPipeline = $True, ValueFromRemainingArguments = $True, Position = 0)]
Process {
$app = "C:\Program Files (x86)\Notepad++\notepad++.exe"
if ($File -ne $null) {
$parameters = '"' + $File + '"'
$options = New-Object "System.Diagnostics.ProcessStartInfo"
$options.FileName = $app
$options.Arguments = $parameters
$options.WorkingDirectory = $pwd
$temp = [Diagnostics.Process]::Start($options).WaitForInputIdle(500)
Invoke-Item $app
function Open($path) {
explorer $path
function Edit-Profile
edit "C:\Users\lennert\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1"
function sleepcomputer
Add-Type -Assembly System.Windows.Forms
[System.Windows.Forms.Application]::SetSuspendState("Suspend", $false, $true)

You can also add other ps1-files from that directory!
More coming up later 😉

In powershell is quite a hassle…

You need this
And this

Yes, that are the only cmdlets available…

Import-Module AdRmsAdmin
Import-Module adrms

First you need to create the virtual drive using new-pssdrive
Call it whatever you want

 new-psdrive -name test -psprovider adrmsadmin -root https://localhost

Browse to it

set-location test:\trustpolicy
or simply cd test:\

And now you have a virtual “drive” containing all the rms configuration.
You can even “dir”  and “cd” in it!

PS test:\trustpolicy\TrustedPublishingDomain> dir
Hive: Microsoft.RightsManagementServices.Admin\AdRmsAdmin::test:\trustpolicy\TrustedPublishingDomain
Id         DisplayName           Type                  CSP                   KeyContainer          CryptoMode
 --         -----------           ----                  ---                   ------------          ----------
 100        tsfdemo2013app1       Internal              AD RMS centrally m... AD RMS centrally m... 2

Here, you can run the cmdlets from the links mentioned above

 PS test:\trustpolicy\TrustedPublishingDomain> Export-RmsTPD -Path .\100 -SavedFile C:\users\tsfadmin.CORP\Desktop\file12
 cmdlet Export-RmsTPD at command pipeline position 1
 Supply values for the following parameters:
 Password: **************
 Please type in a confirmed password:**************
 PS test:\trustpolicy\TrustedPublishingDomain>