SCCM 2012 R2 Installation Script (Part 1)

December 30, 2013 – 2:31 pm

Well, as promised here is the script to setup all the pre-reqs for SCCM 2012 R2.

To run this, you need to copy the files in the D: drive.

You need:

  • An SQL configuration file (SQL2012-ConfigurationFile.ini)
  • An SQL script to set the memory sizes (SetSQLMemory.sql)
  • A VBS script to enable the Windows Update feature (EnableMicrosoftUpdate.vbs)
  • WUInstall (from this link: http://www.wuinstall.com/index.php/en)
  • This script (Install-SCCM2012R2.ps1)
##############################################################################
#
# Script       : SCCM Server Complete Build
# Author       : Marc Bouchard
# Revision     : 12/27/2013
# Description  : Complete installation after base OS deployment
# Parameters   : None
#
##############################################################################

#=============================================================================
# Active Directory integration

Function CheckDomainMembership
{
   write-host -fore green "Checking if server is member of a domain..."
   $ADMember=$false
   do
   {
      if ((gwmi win32_computersystem).partofdomain -eq $false) 
      {
         write-host -fore green "Joining Domain"
         $domain = Read-Host -Prompt "Enter Domain name to join"
         $user = Read-Host -Prompt "Enter User account with DomainJoin permissions [Administrator]"
         if ($user -eq "") {$user="Administrator"}
         $password = Read-Host -Prompt "Enter password for $user" -AsSecureString 
         $username = "$domain\$user" 
         $credential = New-Object System.Management.Automation.PSCredential($username,$password) 
         Add-Computer -DomainName $domain -Credential $credential

$msgtxt = @"
The server must now restart to join the domain.
`
Please log back in with a domain account that has 
ADMINISTRATIVE RIGHTS in order to update the schema.
`
Simply relaunch this script to continue after reboot.
"@

               $Message = new-object -comobject wscript.shell 
               $intAnswer = $Message.popup($msgtxt, 0,"Confirmation",0) 
               Restart-Computer         
      } 
      else
      {
         $ADMember=$true
         write-host -fore green "Server is joined to domain..."
      }
   }
   until ($ADMember -eq $true)
}

#=============================================================================
Function InstallSQLServer
{
   #==============================================
   # Install SQL Server binaries                  
   #==============================================
   do 
   {
      Write-Host "Insert SQL Server 2012 DVD and press any key to continue ..." -ForegroundColor White
      $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
   }
   until (Test-Path -path "R:\setup.exe")

   if (!(Test-Path -path "D:\Scripts\SQL2012-ConfigurationFile.ini"))
   {
      Write-Host "SQL Configuration file missing. Aborting..." -ForegroundColor White
      Break
   }
   Write-Host "Installing SQL Server 2012" -ForegroundColor Green
   CMD /C R:\SETUP /ConfigurationFile=D:\Scripts\SQL2012-ConfigurationFile.ini | Out-Null

   #==============================================
   # Configure Memory Limits
   #==============================================

   CMD /C "D:\Program Files\Microsoft SQL Server\110\Tools\Binn\OSQL.EXE" -E -i D:\Scripts\SetSQLMemory.sql | Out-Null

   #==============================================
   # CONFIGURE SQL INTEGRATED AUTHENTICATION MODE 
   #==============================================

   Write-Host "Set SQL Authentication Mode" -ForegroundColor Green

   # Connect to the instance using SMO
   [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null
   $s = new-object ('Microsoft.SqlServer.Management.Smo.Server') $env:COMPUTERNAME

   # Get current Authentication Mode
   [string]$nm = $s.Name
   [string]$mode = $s.Settings.LoginMode

   If ($mode -ne "Integrated")
   {
      #Change to Integrated Mode
      $s.Settings.LoginMode = [Microsoft.SqlServer.Management.SMO.ServerLoginMode]::Integrated

      # Make the changes
      $s.Alter()

      NET STOP SQLSERVERAGENT
      NET STOP MSSQLSERVER
      NET START MSSQLSERVER
      NET START SQLSERVERAGENT
   }

   #==============================================
   # Install Latest updates
   #==============================================
   Write-Host "Install latest updates for SQL and OS" -ForegroundColor Green
   CMD /C cscript D:\Scripts\EnableMicrosoftUpdate.vbs /nologo

   #!!! Loop WUinstall until no more updates (errorlevel 2)
   D:\Scripts\WUInstallAMD64.exe /install

}

#=============================================================================
# Main Program
#=============================================================================

CLS
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Force

#==============================================
# Set Automatic Windows Update
#==============================================
Write-Host "Enabling Automatic Windows Updates" -ForegroundColor Green
CMD /C cscript %windir%\system32\scregedit.wsf /AU 4

#==============================================
# Execute Custom Functions
#==============================================

CheckDomainMembership
InstallSQLServer

#==============================================
# Install required features 
#==============================================

Write-Host "Installing Features" -ForegroundColor Green

Install-WindowsFeature RSAT | Out-Null
Install-WindowsFeature Web-Windows-Auth | Out-Null
Install-WindowsFeature Web-ISAPI-Ext | Out-Null
Install-WindowsFeature Web-Metabase | Out-Null
Install-WindowsFeature Web-WMI | Out-Null
Install-WindowsFeature BITS | Out-Null
Install-WindowsFeature RDC | Out-Null
Install-WindowsFeature NET-Framework-Features | Out-Null
Install-WindowsFeature Web-Asp-Net | Out-Null
Install-WindowsFeature Web-Asp-Net45 | Out-Null
Install-WindowsFeature NET-HTTP-Activation | Out-Null
Install-WindowsFeature NET-Non-HTTP-Activ | Out-Null

#==============================================

Import-Module ActiveDirectory
Get-Module ServerManager | Out-Null

#==============================================
# Fix Firewall Rules
#==============================================

Write-Host "Modify Firewall Rules" -ForegroundColor Green
CMD /C netsh advfirewall firewall add rule name="SQL / SQL Replication" dir=in protocol=tcp localport="1433,4022"  action=Allow

#==============================================
# Install WSUS
#==============================================

Write-Host "Installing WSUS" -ForegroundColor Green
Install-WindowsFeature -Name UpdateServices-Services,UpdateServices-DB -IncludeManagementTools | Out-Null
CMD /C "C:\Program Files\update services\tools\wsusutil.exe" postinstall CONTENT_DIR=E:\Sources\WSUS\WSUS SQL_INSTANCE_NAME=$env:COMPUTERNAME

#==============================================
# Install ADK
#==============================================
Write-Host "Installing ADK" -ForegroundColor Green
$dwnld = "D:\Scripts\Downloads"
if (!(Test-Path -path $dwnld))
 {
 New-Item $dwnld -type directory | Out-Null
 }
$object = New-Object Net.WebClient
$ADKurl = 'http://download.microsoft.com/download/6/A/E/6AEA92B0-A412-4622-983E-5B305D2EBE56/adk/adksetup.exe'
$object.DownloadFile($ADKurl, "$dwnld\adksetup.exe")
Start-Process -FilePath "$dwnld\adksetup.exe" -Wait -ArgumentList "/quiet /features OptionId.DeploymentTools OptionId.WindowsPreinstallationEnvironment OptionId.UserStateMigrationTool" | Out-Null

#==============================================
# Create Container
#==============================================

   Write-Host "Create OU container" -ForegroundColor Green

   $root = (Get-ADRootDSE).defaultNamingContext

   # Check if System Management OU already exists
   $ou = $null

   try
   {
      $ou = Get-ADObject "CN=System Management,CN=System,$root"
   }
   catch
   {
      Write-Host "System Management container does not currently exist."
   }

   if ($ou -eq $null)
   {
      $ou = New-ADObject -Type Container -name "System Management" -Path "CN=System,$root" -Passthru
   }

   # Get the current ACL for the OU
   $acl = get-acl "ad:CN=System Management,CN=System,$root"

   # Get the SCCM Server's SID (the LOCAL machine)
   $computer = get-adcomputer $env:ComputerName
   $sid = [System.Security.Principal.SecurityIdentifier] $computer.SID

   # Create a new access control entry to allow access to the OU
   $adRights = [System.DirectoryServices.ActiveDirectoryRights] "GenericAll"
   $type = [System.Security.AccessControl.AccessControlType] "Allow"
   $inheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] "All"
   $ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $sid,$adRights,$type,$inheritanceType

   # Add the ACE to the ACL, then set the ACL to save the changes
   $acl.AddAccessRule($ace)
   Set-acl -aclobject $acl "ad:CN=System Management,CN=System,$root"

#==============================================
# Extend Schema
# Note: Requires SCCM ISO mounted
#==============================================
   do 
   {
      Write-Host "Insert SCCM 2012 DVD and press any key to continue ..." -ForegroundColor White
      $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
   }
   until (Test-Path -path "R:\SMSSetup\BIN\x64\ExtADSch.exe")

   Write-Host "Extending Schema" -ForegroundColor Green
   CMD /C R:\SMSSetup\Bin\x64\ExtADSCh.exe

##############################################################################
# INSTALLATION COMPLETED
##############################################################################

Write-Host "DONE!" -ForegroundColor Green

SCCM, SQL and PowerShell

December 27, 2013 – 9:16 pm

I also got involved with pretty much every aspect of the new environment (it’s a consolidation project), with Active Directory, SQL Server, SCCM 2012, etc…

Having last worked with SMS 2003 R2, I decided to start playing with SCCM 2012. Foundations are the same as SMS so far, so nothing too complicated (other than the whole management console itself has changed 🙂 ). But being in a scripting mood, I decided to automate the whole installation process.

Start from a new VM, with 4 virtual disks (C:, D:, E:, and … F: )

  • C: = OS Only
  • D: = Applications
  • E: = Data
  • F: = Backups (SQL Exports)

Vmware_4Disks

Which means I have to rename the virtual CD drive to something else (my standard is R: for … Reader…).

So my initial build looks like this:

  • Change the Optical Drive letter to R:
  • Initialize all the virtual disks
  • Set all the volume labels

And while at it, clear all the event logs (I like starting with clean logs before installing new apps. Easier to spot the issues…)

Here’s the code for this script, which I call “Prep-New-Server.ps1” (Again, I didn’t reinvent the wheel, just learning and having fun with Powershell)

#################################################
# Function: ChangeDriveLabel                    #
# Params:                                       #
# - Drive Letter                                #
# - New Drive Label                             #
#################################################

Function ChangeDriveLabel([string]$DriveLetter, [string]$NewLabel)
{
If ((New-Object System.IO.DriveInfo($driveletter)).DriveType -ne 'NoRootDirectory')
    {
    $drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = '$DriveLetter'"
    Set-WmiInstance -inputobject $drive -Arguments @{DriveLetter="$DriveLetter"; Label="$NewLabel"}
    }
}

#################################################
# Function: ChangeOpticalDriveLetter            #
# Params:                                       #
# - Drive Letter                                #
#################################################

Function ChangeOpticalDriveLetter([string]$DriveLetter)
{
    (gwmi Win32_cdromdrive).drive | %{$a = mountvol $_ /l;mountvol $_ /d;$a = $a.Trim();mountvol $DriveLetter $a} | Out-Null
}

#################################################
# Function: InitNewDisks                        #
#################################################

Function InitNewDisks
{
    Get-Disk | Where PartitionStyle -eq 'raw' | Initialize-Disk -PartitionStyle MBR
    $NewDisks=Get-Disk | Where NumberOfPartitions -eq 0 | sort Number
    Foreach ($Nb in $NewDisks)
    {
        $NewPartition=New-Partition -DiskNumber $Nb.Number -AssignDriveLetter -UseMaximumSize
        Sleep 2
        $NewPartition | Format-Volume -FileSystem NTFS  -Confirm:$false
    }
}

#################################################
# Function: ClearAllEvents                      #
#################################################

Function ClearAllEvents
{
    wevtutil.exe el | ForEach-Object {wevtutil.exe cl "$_"}
}

#################################################
# Main Program                                  #
#################################################
ChangeOpticalDriveLetter "R:" | Out-Null
InitNewDisks
ChangeDriveLabel "C:" "OS" | Out-Null
ChangeDriveLabel "D:" "Apps" | Out-Null
ChangeDriveLabel "E:" "Data" | Out-Null
ChangeDriveLabel "F:" "Backups" | Out-Null
ClearAllEvents

#################################################

After running this, I’m ready for the SCCM installation (or anything else for that matter… This is pretty much standard VM deployment configuration (with or without the F: drive if there are no SQL servers on the box).

To keep this short, I will post the SCCM script in a future post!

State of things…

December 27, 2013 – 9:01 pm

I have lost a little of my drive to study in the past year, I guess I gave too much the year before with the CCNP, CCNA Security, and the MCSE 2012 🙂 Soooo… I’m trying to get back into it a bit.

I have moved to a new mandate, doing the detailed design for a VMware vSphere deployment (2 vCenters, 24 hosts). While configuring things, I wanted to use PowerCLI to automate certain configurations (especially since I had to repeat them on both environments). And… I got hooked I guess !

I joined that project a bit late in the game, some of the deployment tasks were already done (they had already built about 200 VMs). All of them with E1000 interfaces… So after scouring the net for scripts to automate the upgrade, I customized and rearranged pieces of code that I found to come up with a great script that works really well. I will post it here when I get back to work and grab my latest update.

Basically, it checks if the virtual NIC of a VM is E1000, captures the IP information, shuts down the VM, changes the NIC type to VMXNET3 (retaining the MAC address), sets the “automatically update the VM Tools at power up” feature, starts the VM, runs external tools to remove ghost devices, disables IPv6 (client requirement), restores the IP information, disables automatic DNS registration and restarts the VM one last time.

Oh and if you call the script with a cluster name instead of a VM, it runs on all VMs in the cluster 🙂 So yeah, I didn’t reinvent the wheel but I made it work for my client’s needs.

To be continued…

Summertime!

August 1, 2013 – 11:27 am

It’s been a while since my last update! My current mandate is almost over, what started as a 3 week replacement for a sysadmin lasted almost 2 years overhauling the entire infrastructure, going from a room full of standalone physical servers on 100mbps network with cabling issues, to a modern network with 10GB backbone, gigabit to the desktop, 99% virtualised back-end on shared storage and blade servers, disaster recovery solution, etc…

This was my most challenging and stimulating mandate ever. I worked with a great IT manager who trusted me and gave me the latitude to learn and experiment while deploying all of this, I also learned a lot of new technologies/products.

I hope my next one will be even better 🙂

I am taking the summer off from studying (well I started the CCDA curriculum but I put everything on hold to relax a bit). Once I know what my next mandate is, I’ll resume the studies.

I am considering the following for next year:

  • CCDA/CCDP
  • VMware View
  • Microsoft Exchange 2013
  • And possibly Cisco UCS (ain’t that a cool product!)

CCNA Security update

May 30, 2013 – 7:24 am

With the experience acquired in the past year, designing and securing my client’s network, the contents of the CCNA Security curriculum was very easy to review. Yesterday, I passed with success the 660-554 exam 🙂

I was once very proud to have passed the CCNA exam, as I had very little knowledge of telecom, having spent most of my career working with Microsoft and more recently VMware products (since ESX 2.x). I amazed myself by getting the CCNP R&S last year, thinking that was it for me and it seems I’ve got the Cisco bug. Next is CCDA and CCDP. I probably never will go for the CCIE, since I’m not working solely in that field, but I will continue to learn as much as I can just for the sheer pleasure of learning 🙂

Trend Micro Deep Security Manager 9 and SSL certificates

May 24, 2013 – 9:41 pm

After installing DSM v9, I wanted to change the self-signed SSL certificate the application generates to one from my client’s Microsoft PKI infrastructure. The instructions in the installation manual for DSM 9 were not very helpful, some steps didn’t apply to a Microsoft PKI generated certificate. Further searching (and a phone call to Trend Micro) didn’t get me the answer I needed (the support technician wanted me to simply “accept” the self-signed certificate at first)… He pointed me an older document for v7 (HERE) that still didn’t fix it for me but helped me figure things out.

The documentation says to import the certificate chain, so I saved the CA chain in a P7B file but the import tool wouldn’t recognize the file, resulting in this error message: Input not an X.509 certificate.

However, Microsoft’s Certificate Server only outputs CA chains in this format.

We have a 2 tier PKI infrastructure, with a root and an issuing server. I saved both certificates and tried importing them both as with the “root” alias, but obviously I was getting an error with the 2nd certificate (alias already exists). So I tried importing the real root certificate using the “root” alias, then the issuing certificate under a new alias called… “issuing”, then the main certificate using the “tomcat” alias, and all went well.

Since I have a 2nd server to prepare, I wrote a script for future use and to share with whomever might need it, to simplify the certificate change. Hope someone out there finds it useful!

 

@ECHO OFF
ECHO NOTE: This script must be run from the root of the drive where Deep Security Manager is installed.
CLS
CD "\Program Files\Trend Micro\Deep Security Manager"
SET PATH=%PATH%;jre\bin

:: Check for parameter (password). If missing, show help message
IF "%1" == "" GOTO HelpMsg
net stop "Trend Micro Deep Security Manager"
keytool -delete -storepass %1 -alias tomcat -keystore .keystore
keytool -genkey -storepass %1 -alias tomcat -keyalg RSA -keystore .keystore
ECHO.
ECHO When asked for your first and last name, enter the name of the DSM server (i.e. DSMSERVER.COMPANY.COM)
ECHO.
keytool -certreq -storepass %1 -keyalg RSA -alias tomcat -file d:\certreq.txt -keystore .keystore

ECHO.
ECHO Create request on the PKI Server using the request file created (D:\CertReq.txt)
ECHO then copy the following files in the root of the D: drive
ECHO.
ECHO - root.cer (root certificate)
ECHO - issuing.cer (issuing root certificate)
ECHO - certnew.cer (certificate for the server)

ECHO.
ECHO Press any key to continue when ready to proceed
PAUSE > NUL

keytool -import -alias root -storepass %1 -trustcacerts -file d:\root.cer -keystore .keystore
keytool -import -alias issuing -storepass %1 -trustcacerts -file d:\issuing.cer -keystore .keystore
keytool -import -alias tomcat -storepass %1 -file d:\certnew.cer -keystore .keystore
net start "Trend Micro Deep Security Manager"
GOTO End

:HelpMsg
ECHO Get the password from the installfiles\genkey.bat after the -storepass parameter
ECHO.
ECHO Contents:
ECHO.
TYPE installfiles\genkey.bat
ECHO.
ECHO.
:End

CCNA Security – Tips

May 16, 2013 – 10:15 pm

I am almost done with the CBT Nuggets training video for CCNA Security. I started experimenting in my lab and from the get go, had some issues with CCP (Cisco Configuration Professional). The tool is having issues under Windows 8.

First, you need to go to Internet Explorer 10, select Tools, then compatibility view settings. Add 127.0.0.1 to the list and click OK. This will fix the issue where about 1/4 of the display is filled and the rest is blank.

And lastly, you need to run it as Administrator (right-click, Run As Administrator).

Header

May 10, 2013 – 7:37 pm

Finally found a few minutes to update the header/logo of the blog. It was so out of date I had to replace all 3 logos 🙂 Been busy!

Microsoft Certified Solutions Expert: Server Infrastructure

May 10, 2013 – 10:06 am

Well, this week I completed the requirements for the MCSE on Windows Server 2012. I really enjoy challenging myself to get those certifications. So much that now that I’ve completed this one, I find myself wondering what to do with my evenings lol… Get a life you say? Probably… I just love technology. I am almost finished with my current mandate, I might wait and see what the next job will be to jump on something relevant. Then again, I have the CCDA and CCNA Security books staring at me right now, so who knows. Exchange 2013 sounds appealing also. And VMware View. And… And… 🙂

Virtualizing applications

April 16, 2013 – 6:36 pm

Thinapp seems relatively easy at first, but don’t let it mislead you. You need skill to do this stuff! I spent hours and hours packaging Access 2010 for a current project. I thought I would share my build “recipe” for this…

Build VM

VMware Workstation is recommended for the packaging environment.

  • Create new VM with no audio, USB, floppy, printer, 1GB RAM, 1 CPU
  • Install Windows 7 SP1 – 32 bits with all hotfixes
  • Install Microsoft Update (to enable patching Office components)
  • Disable Windows Defender, Security Services

Initial Preparation

  • Copy ThinApp 4.7.3 or later executable folder to a desktop folder
  • Copy Access 2010 English to a desktop folder
  • Disconnect the NIC to ensure Access will not activate
  • From the Access folder, run SETUP /ADMIN to create an MSP package with at least these parameters:
    • Install location: C:\Office
    • Licensing and user interface
      • Use KMS client key
      • Display level: Basic, Suppress modal
    • Modify Setup Properties
      • Property Name: KMSSERVICENAME
      • Value: KMS.YOURDOMAIN.COM (I recommend creating a DNS CNAME for this)
      • Property Name: AUTO_ACTIVATE
      • Value: 1
    • Set Feature Installation States to install what you need only.
    • Save the MSP
  • Launch ThinApp Setup Capture and run the PRESCAN.

Take a snapshot image of the workstation.

  • Run the installation with the custom MSP package “setup /adminfile custom.msp”
  • Once the installation is completed, activate the NIC
  • Install all product service packs and hotfixes from Microsoft Update
  • Disconnect the NIC again.
  • Open Access and make sure it is not yet activated (File, Help)
  • When the Help Protect and Improve Microsoft Office popup appears, select “Don’t make changes”
  • Create a new database (this creates the system.mdw file needed for workgroup administrator).
  • Delete the new database
  • Open an elevated Command Prompt, and run those 2 commands
    • C:\Program Files\Common Files\Microsoft Shared\OfficeSoftwareProtectionPlatform\OSPPREARM.EXE
    • net stop osppsvc

Note: The first command re-arms the license (it resets the CMID used of KMS licensing), while the second turns the Office Protection Platform service off.

PostScan

  • Run ThinApp POSTSCAN
  • Select only the main Access entry point
  • Change the Inventory name to something appropriate for your use.
  • Select the “Full Write Access” isolation mode
  • Change the capture path to C:\Captures\packagename (or wherever you prefer)
  • Enable the NIC
  • Map to a network share
  • Copy the C:\Captures\packagename folder to your share
  • Set the following folders to MERGED by editing the ##ATTRIBUTES.INI in the root of each
    • %APPDATA%\MICROSOFT\
    • %APPDATA%\MICROSOFT\AddIns\
    • %APPDATA%\MICROSOFT\Office\
    • %APPDATA%\MICROSOFT\Access\
    • %APPDATA%\MICROSOFT\Templates\
    • %Drive_C%\Office\Office14\
    • %LOCAL APPDATA%\
    • %LOCAL APPDATA%\MICROSOFT\Office\
    • %TEMP%\ (Create if missing)
  • Remove extra folders
    • %Fonts%
    • %Drive_C%\MSOCache
    • %Systemroot%\Installers

Customize package

Following doesn’t seem to be required but verify anyway.

  • Move the OfficeSoftwareProtectionPlatform folder
    • from %drive_C%\USERS\All Users\Microsoft
    • to %Common AppData%\Microsoft
  • Set the following folder an   d subfolders to WRITECOPY
    • %Program Files Common%
    • %ProgramFilesDir%

 

HKEY_CURRENT_USER.txt

  • Put the following at the beginning of the file

HKEY_CURRENT_USER.INCLUDE

HKEY_LOCAL_MACHINE.txt

  • Put the following at the beginning of the file

HKEY_LOCAL_MACHINE.INCLUDE

PACKAGE.INI

  • Uncomment the line MSIStreaming=0 and set the value to 1
  • Uncomment the line VirtualComputerName and set the value to the package name and work revision ex: ACCESS2010_01
  • Uncomment the line VirtualizeExternalOutOfProcessCOM=0
  • Add the following lines after the above:

ChildProcessEnvironmentExceptions=WINWORD.EXE;EXCEL.EXE;POWERPNT.EXE;OUTLOOK.EXE;MOC.EXE

ChildProcessEnvironmentDefault=Virtual

[FileList]
ExcludePattern=*.bak,*.msi,*.mst,*.cab,*.msp