My Profile Photo

Spencer Owen

The art of progress is to preserve order amid change and preserve change amid order - Alfred North Whitehead

CHEF on Windows - Promote to local administrator

The world of Automation on Windows, sometimes requires that you run a script as a local administrator account.

In powershell/batch the command to add and remove a domain account to local administrators is:

net localgroup administrators\someuser /add

To automate this with chef, do this:

  batch 'promote user' do
    code <<-EOH
      net.exe localgroup administrators #{node['domain']}\\#{some_user} /add
    action :run
    notifies :run, 'batch[demote user]', :delayed

Then to demote that user at the end of the chef run (because you don’t want to leave domain admin accounts just laying arround)

batch 'demote user' do
    guard_interpreter :powershell_script
    code <<-EOH
    net.exe localgroup administrators #{some_user} /delete
    only_if "[boolean](net.exe localgroup administrators  | where {$_ -match '#{some_User}'} )"
  action :run

Note that you need to ensure proper idempotency by using an only_if statement. In the demote resource, I’m using a powershell_script as a guard interpreter, but running the actual command as batch.

Additional Windows Automation

In windows, if you need to run a command as another user, you have a couple of options.

  1. Use Invoke-Command

The problem with Invoke-Command is that it is intended to be executed on a remote host. While you can pass in . or <localhostname> as a parameter, that only works if you user has remote access enabled.

The most commonly suggested workaround from the community, is to run the script as a scheduled task.

Luckily, the windows cookbook has a scheduled task resource called windows_task

#You will need to include the windows cookbook

template 'start_regall.ps1' do
  source 'start_regall.ps1.erb'
  path "c:\\start_regall.ps1"
    :user            => "#{node['domain']}\\#{some_user}",
    :password        => "#{user_password}",
  action :create

windows_task 'regall' do
  user     "#{node['domain']}\\#{some_user}"
  password "#{user_password}"
  command  "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -noprofile -noexit -executionpolicy Bypass -File 'c:\\start_regall.ps1'"
  action [:create,:run,:delete]
  run_level :highest
  force true

This code could likely be cleaned up a bit, but is pretty bulletproof in my tests.

  1. Use Microsoft Desired State Configuration

Newer versions of chef support the microsoft Desired State Configuration API

Take a look at the dsc_resource and dsc_script chef resources