Thursday, July 14, 2011

FirstLogonCommands to configure your images on deployment when user context is required

This is an old trick and I am sure that there are more elegant ways to handle this.  However, I thought I would share how I am using AutoAdminLogon and FirstLogonCommands in my sysprep unattend answer file to do some heavy lifting for me to drive modifying server settings and application install and configuration.

This came about through using an Azure VM role and being forced to complete as much setup as I can without having to get to the console of the VM.  It is amazing how much you can automate when you get creative.

Let me get one thing out of the way:  Can this be used securely?  Sure, why not, with some proper precautions.  First, encrypt your admin user password; second, don’t use the built-in administrator; third, know that no one can get to the console of the machine (totally headless); fourth, disable the admin account and logout as your last step.

All of the settings that I am referring to are in the “Microsoft-Windows-Shell-Setup” section of your unattend.xml answer file.

First – you have to create and provide a password for the local administrator account.  Note, I am naughty by using the built-in local administrator.

<UserAccounts>
  <AdministratorPassword>
    <Value>IdidntEncryptMineButYouShould</Value>
    <PlainText>true</PlainText>
  </AdministratorPassword>
</UserAccounts>

Then I need to enable AutoAdminLogon

<AutoLogon>
  <Password>
    <Value>IdidntEncryptMineButYouShould</Value>
    <PlainText>true</PlainText>
  </Password>
  <Username>Administrator</Username>
  <LogonCount>1</LogonCount>
  <Enabled>true</Enabled>
</AutoLogon>

Then I define all of my tasks that run when the first user with administrator credentials logs on to the machine:

<FirstLogonCommands>
  <SynchronousCommand wcm:action="add">
    <Order>1</Order>
    <CommandLine>C:\MyFolder\vjRedist64\install.exe /q</CommandLine>
    <Description>Install Visual J# Redistribution</Description>
  </SynchronousCommand>
  <SynchronousCommand wcm:action="add">
    <Order>2</Order>
    <CommandLine>%WINDIR%\System32\WindowsPowerShell\v1.0\PowerShell.exe -command start-sleep 120</CommandLine>
    <Description>Wait for j# install</Description>
  </SynchronousCommand>
  <SynchronousCommand wcm:action="add">
    <Order>3</Order>
    <CommandLine>%WINDIR%\System32\WindowsPowerShell\v1.0\PowerShell.exe -command Import-Module ServerManager; Add-WindowsFeature Web-Server; Add-WindowsFeature Web-Asp-Net; Add-WindowsFeature Web-Windows-Auth; Add-WindowsFeature Web-Metabase</CommandLine>
    <Description>Add ASP.Net and IIS6 Metabase compatibility</Description>
  </SynchronousCommand>
  <SynchronousCommand wcm:action="add">
    <Order>4</Order>
    <CommandLine>%WINDIR%\System32\WindowsPowerShell\v1.0\PowerShell.exe -command set-executionpolicy remotesigned -force >> C:\Users\Public\Documents\setExecution.log</CommandLine>
    <Description>Set the ExecutionPolicy to RemoteSigned for the setup script to run</Description>
  </SynchronousCommand>

</FirstLogonCommands>

Note that there is a sequence number, this way you can simulate a workflow by having having your tasks or scripts execute in a synchronous order.  You just have to watch out for those tasks that run off on their own threads and don’t execute within the context of the command windows where the script executes (that Visual J# installer is a perfect example).  You can manage these spawned processes with PowerShell, but not with a batch command.

6 comments:

Unknown said...

If I have 2 scripts I put in the FirstLogonCommand in my unattend.xml, does it:

1. only run one time when an admin logs in? OR does it log in everytime any admin or user logs in?

Besides the above, as an alternative I was going to create 2 Powershell scripts to run 2 scripts in the RunOnce key in hoping to achieve the above. thanks,

Unknown said...

If I have 2 scripts I put in the FirstLogonCommand in my unattend.xml, does it:

1. only run one time when an admin logs in? OR does it log in everytime any admin or user logs in?

Besides the above, as an alternative I was going to create 2 Powershell scripts to run 2 scripts in the RunOnce key in hoping to achieve the above. thanks,

BrianEh said...

FirtLogonCommand runs only the first time the user logs on.

RunOnce runs just once, can be set any time, is not necessarily the first logon.

In both cases you have to pay attention to who is logging on and when in any sequence of events.

Unknown said...

Brian- thanks for your feedback, just want to double check I understand. An admin is always the first to log in after a computer is reimaged in my environment to make sure everything is working for the user. So, since that is the case, it will run that one time and not ever again unless I reimage the machine again, is that correct?
One other related question, After I created a base image with the unattend.xml file I created another script to delete the unattend.xml file from the computer once the Windows Setup is finished with them (this file is copied into the panther directory during setup hence the two lines)
so will it only work one time?
thank you again.

Unknown said...

Brian- thanks for your feedback, just want to double check I understand. An admin is always the first to log in after a computer is reimaged in my environment to make sure everything is working for the user. So, since that is the case, it will run that one time and not ever again unless I reimage the machine again, is that correct?
One other related question, After I created a base image with the unattend.xml file I created another script to delete the unattend.xml file from the computer once the Windows Setup is finished with them (this file is copied into the panther directory during setup hence the two lines)
so will it only work one time?
thank you again.

BrianEh said...

The unattend.xml is processed once. At the time of mini-setup as a machine exits its sysprep'd state.

The unattend.xml can be in three default paths that Windows will automatically look for it, or the unattend.xml can be explicitly declared at the time that sysprep is run.

This is all related to Windows Deployment in general.
And there are lots of excellent documents on this, as it has fundamentally not changed in many released, only the options that can be defined in an unattend.xml.

Some events process as a user logons on, Some events process at startup, etc.

Check the documentation in regards to the options to keep that straight.