Deploying Operating systems with MDT, SCCM, Orchestrator and SCSM – part 1

I intend this to be a series of blog posts about my experience in implementing end to end OSD solution. I will be writing about my lab implementation, as production version has much unneeded clutter that would just confuse the whole blog post.

I thought this blog series would be split in following posts:

  1. Intro
  2. Lab setup
  3. MDT
  4. SCCM
  5. Intel AMT
  6. Orchestrator
  7. SCSM
  8. Bringing it all together
  9. Recap

This is a rough outline that I in vision at the beginning of writing, so it will probably change. I will link the following posts back to these bullet points for easier following.

So without further ado, let get stuck in. First, let’s try to sum up what we will be doing and why.

INTRO:

There are a few goals I would like to achieve with OSD deployment process, I will explain reasoning for them below:

  • Monitor deployment from end-to-end from help desk technicians workstation
  • Deploy OS to known rather than unknown computers
  • Support computer Replace and Refresh scenarios besides bare metal deployment
  • In Replace and Refresh scenarios ensure user data is preserved
  • Enable self service portal for requesting OSD
  • In refresh scenarios do not use PXE boot

Monitoring OSD is achieved in 3 steps. One is enabling monitoring in MDT. This gives us the ability to check on progress of all deployments. Second is enabling DaRT in conjunction with MDT monitoring. This gives the ability to “remote” into WinPE and see remote screen from out workstation. This is very useful for when errors occur and we need to troubleshoot. The third option we will enable is Intel AMT. With this we get the ability to connect to computer event when it is turned off. We can adjust BIOS settings, force it to use specific device for boot at next start-up and most importantly, from monitoring perspective, we get the ability to connect to it using VNC. Now we can see and interact with remote computer all the way from start to finish.

More about monitoring in the following posts. We will also answer questions like, why DaRT and Intel AMT, and not just the latter?

Why deploying OS to “known” rather than unknown computers? When deploying OS with SCCM you have two basic options, you can deploy your task sequence to Unknown computers, or you can deploy to other collections. If you deploy to unknown computers you can just start any new computer, PXE boot it and windows will install, sort of 🙂 BUT, what will the name be? MININT-****** does not suit you? OK then. MDT to the rescue! You can add computers to MDT DB and give it a name. OK. Good. Computer is still Unknown from SCCMs point of view, so it will deploy OS to it, but the computer is “known” from MDTs view, so it will get correct name and all other settings that you put in there.

So, what is the downside to this kind of deploying? Well say you want to Replace a computer. You would have to make a computer association in SCCM, which cannot be done until new computer is finished deploying. And since we are already importing computers to MDT prior to actually deploying them, why not create them in SCCM as well?

Another upside for this would be that you completely control who can deploy computers. No more need for protecting PXE sites with passwords and enabling F12 for extra protection. If computer is not assigned for a deployment, it will not have anything to deploy.

Support computer Replace and Refresh scenarios besides bare metal deployment is described in previous paragraph. This requirement is directly linked and dependent on deploying to known computers.

In Replace and Refresh scenarios ensure user data is preserved requirement leverages USMT at its core. Basically what it does it copies users data from old computer to a new one, or in case of Refresh, it makes sure it is copied back to computer. But since we are also using SCCM, it ensures that all programs are installed on new computer.

Enable self service portal for requesting OSD.  With SCSM self service protal, we can enable users to request Refresh scenarios for their own computers, or if you find this too risky:) help desk technicians can do this for any user and never leave their desk. This way we do not to distribute any scripts, help desk does not have to ask administrators every time a computer needs to be deployed to put it in MDT, … just point them to SCSM Self Service portal, where they fill out a form and wait.

In refresh scenarios do not use PXE boot was not requirement in the beginning, but once I found it, it was a must. I will go in depth why we need this so badly. I’ll give you a hint, it has to do with TFTP. 🙂

OK. I think we covered all the objectives, and why they matter, now lets go to our LAB environment.

  1. Intro
  2. Lab setup
  3. MDT
  4. SCCM
  5. Intel AMT
  6. Orchestrator
  7. SCSM
  8. Bringing it all together
  9. Recap

This is a rough outline that I in vision at the beginning of writing, so it will probably change. I will link the following posts back to these bullet points for easier following.

Advertisements

Automating DCOM ACL with PowerShell

Sometimes you need to set explicit permissions on DCOM objects. You can do this using dcomcnfg.exe. With dcomcnfg.exe you can set permissions on all DCOM objects on a computer. However, this is doing it manually. 🙂 If you ever need to automate this step, you can do it using PowerShell, and here is how. Please note you have to run PowerShell as Administrator.

dcomcnfg

Automating DCOM ACL with PowerShell

There are 5 steps to configure DCOM ACL.

1.) Get WMI object

2.) Get Descriptor

3.) Create Trustee and assign it rights

4.) Add Trustee to Descriptor

5.) Set WMI object

In step one, we get WMI object for DCOM application we want to set permissions. In below example, we get settings for Messaging application

$wmi = Get-WmiObject -Class Win32_DCOMApplicationSetting -Filter ‘caption=”Messages”‘ -EnableAllPrivileges

In step two we get current security descriptor for this object, so we can add permissions to existing set. We can get and set permissions for all 3 types

$descL = $wmi.GetLaunchSecurityDescriptor().descriptor
$descA = $wmi.GetAccessSecurityDescriptor().descriptor
$descC = $wmi.GetConfigurationSecurityDescriptor().descriptor

Image from GUI:

dcomcnfgSec

In step three we create our own trustee object, which we will use to assign rights to. It consists of Domain, username and permissions we would like to assign to it. In this example we will set all permissions to allow to user object Interactive.

$trusteeObj = ([wmiclass]’Win32_Trustee’).psbase.CreateInstance()
$trusteeObj.Domain = “NT authority”
$trusteeObj.Name = “Interactive”

$ace = ([wmiclass]’Win32_ACE’).psbase.CreateInstance()
$ace.AccessMask = 31
$ace.trustee = $trusteeObj

If you need to set different permissions then in example above, you can get AccesssMask values by manually setting permissions in GUI as you need them and then read them using PowerShell. In step two we got current descriptor, from which we can read current permissions.

First we need to get DACL list:

$descL.[X].DACL

in this object you have current Trustee and it’s AccessMask.

From here on it is very simple…

In step four we add our object we created in step 3 to descriptor

$descL.DACL += [System.Management.ManagementBaseObject]$ace
$descA.DACL += [System.Management.ManagementBaseObject]$ace
$descC.DACL += [System.Management.ManagementBaseObject]$ace

And in step five we write is back using WMI.

$wmi.SetLaunchSecurityDescriptor($descL)
$wmi.SetAccessSecurityDescriptor($descA)
$wmi.SetConfigurationSecurityDescriptor($descC)

We can see the changes we made using dcomcnfg.exe or PowerShell

dcomcnfgSec2

Again, do not forget to run PowerShell as Administrator! 😉

Code is available for download on TechNet:

https://gallery.technet.microsoft.com/Set-DCOM-ACL-with-650fa48d

Hope this helps you.

Delete Disabled Profiles from Computers

Your users are connecting to terminal server, so they can use an application, and everything works just fine, until one day, a user can’t connect. You swing into action and find out, that the problem lies on your hard drive, or better yet, lack of it. You ran out of disk space on your terminal server. You check what is taking up most of the disk space, and you see there are dozens and dozens of user profile folders. now, you could go, and delete just the folders, but that results in users getting temp profiles. The other option is, to go to advanced settings of your system, and delete profiles from there, But how do you know which ones to delete?

UserProfiles

You could delete just the biggest ones, but the User Profiles dialog does not allow you to make any kind of sorting. The other thing you could do, this being a terminal server, is delete all profiles, but one by one? Who wants to do this. You guessed it, a script.

I wrote a script that  does just that. It is available on Technet Gallery, https://gallery.technet.microsoft.com/Delete-Disabled-profiles-06d4e82a.

To be able to run it, you must have administrator privileges on target computer and installed Active Directory module on computer running it.

It only works on Windows Vista/Server 2008 and above, as before that, the WMI class I use, did not exist.

Enjoy it, and save your disk space. 🙂

Empty Credential Manager store

We all know, that Windows enables us to save our credentials when we connect to other systems. One example would be Remote Desktop Connection, mstsc.exe. You can choose to save your username and password, so the next time, you can connect more easily. Well these credentials have to be saved somewhere, which can

A) Cause problems when you change your password

B) Present a security risk, since all your passwords are saved on a disk

You can delete these saved credentials by opening Credential Manager from Control Panel and Remove one-by-one. But, if you have many, that is not really an option. So it’s script time:

cmdkey /list | %{ if($_.startswith(”    Target:”)){cmdkey “/delete:$($_.split(‘=’)[1])”} }

This simple one line, run from within PowerShell, will remove all your Windows Credentials entered in your Credential Manager.

Hope it helps you.

Converting SCCM 2012 custom reports to use RBAC. 

In SCCM 2007 we had many custom reports that were needed by different people. Often it was the same report, with just one parameter differing, so it was displaying information user needed, but nothing more. For example administrators in different countries were only able to see reports about computers in countries they were responsible for, but not others.

Now in our company this quickly meant over 200 reports. in fact it was just 8 or 10 reports, differing in names, one filter value and permissions on them.

With upgrade to SCCM 2012 i thought it would be a good time to update our reports as well. And since SCCM 2012 enables us to use RBAC, I gave it a go. Firstly you have to set permissions for users. I will explain how to do this in another post. For now let’s just say that users have permissions correctly assigned to them.

If you are creating new report, rather than reusing old ones, you can skip first couple of steps and just open Report Builder. Continue reading

Powershell to sanitize GPO

Quick ways to sanitize GPOs with Powershell.

Did you ever wonder how many GPOs do you have that do not have any links?

GPOLinking

Or if there are any users that were assigned Security Filterings on GPO, but have since been deleted?

 

GPOFiltering

 

Here is are two quick “scripts”, that will find you just that, so you can further investigate and “sanitize” your Group Policy Objects.

# Get all GPO that are not linked to anything
Get-GPOReport -all -ReportType xml | %{([xml]$_).gpo | select name,@{n="SOMName";e={$_.LinksTo | % {$_.SOMName}}},@{n="SOMPath";e={$_.LinksTo | %{$_.SOMPath}}} | % {if($_.SOMPath -eq $null){$_}}}

#
# Get all GPO objects, that have permissions set to deleted users (No DisplayName, just SID)
$gpo = Get-GPO -all; $gpoo =@();$gpo | % {$aa = $_;$_| get-gppermissions -all | %{ if($_.trustee.name -eq $null){if($gp.contains($aa.DisplayName)){} else{$gp += $aa.DisplayName} } }}; $gp