Bulk assigning O365 licenses, and then some… using Powershell

Managing our O365 licenses got me an idea to write one of my first Powershell scripts.

The script is tailored to our environment, but can be altered to fit any needs without much hassle. The script looks for users in specified OUs and compare them to what users in O365 that are assigned a license. All users in the specified OU are being assigned the specified license. If a license is assigned to a user, who does not exist in the specified OUs, the license is automatically removed. This way I’m always on top of who is using our licenses.

The script does the following for you in details:

  • (#2) Connects to O365 through Powershell (pre-req for that can be seen here: https://technet.microsoft.com/en-us/library/dn975125.aspx)
  • (#3) Reads what license you want to assign your users in the process. Change this to fit your needs and replace tenantname with your O365 tenant.
  • (#4) Reads what conditions you have for filtering what O365 users that needs a license. I’m excluding my Office 365 Admin and a few others, as I don’t wanna mess with the license for those users.
  • (#5) Reads the OUs containing user who needs a O365 license. You can specify several OUs if needed.
  • (#6) Assign the location and license for each user found in OUs. You can filter additionally in this step if needed.
  • (#7) Remove the O365 license, if user is not found in specified OUs. Change this to fit your needs and replace tenantname with your O365 tenant.
#_1_Imports relevant modules.
Import-Module ActiveDirectory
Import-Module MSOnline

#_2_Prompt for credentials used to log into O365.
$usercredentials = Get-Credential
Connect-MsolService -Credential $usercredentials

#_3_What license are we assigning the users.
$O365License = "tenantname:ENTERPRISEPACK"

#_4_Conditions for O365 users. Excluding certain accounts
$conditions = {$_.isLicensed -eq "TRUE" -AND $_.DisplayName -ne "Office 365 Admin" -AND $_.DisplayName -ne "Expectacademy" -AND $_.DisplayName -ne "London Printer"}

#_5_What OUs are we searching in.
$OUs = "CN=Schema,CN=Configuration,DC=EUROPE,DC=TEST,DC=CONTOSO,DC=COM","CN=Schema,CN=Configuration,DC=EUROPE,DC=TEST,DC=CONTOSO,DC=COM"

#_6_Search the OUs and return to variable. For each emailaddress found, assign to KR O365 license
$out = ForEach ($OU in $OUs) {get-aduser -SearchBase $OU -SearchScope 'Subtree' -Properties '*' -filter {(Description -ne 'Do not delete DMSForLegal') -AND (Enabled -eq $true)} | Select-Object UserPrincipalName}
$O365Users = Get-MsolUser -all | Where-Object $conditions | Select-Object UserPrincipalName
ForEach ($user in $out)
{
    $upn=$($user.UserPrincipalName)
    Set-MsolUser -UserPrincipalName $upn -UsageLocation DK
    Write-Host "Setting location to DK for $($user.UserPrincipalName)"

    Set-MsolUserLicense -UserPrincipalName $upn -AddLicenses $O365License -erroraction 'silentlycontinue'
    Write-Host "Assigning $($O365License) license for $($user.UserPrincipalName)"
}
#_7_For each user assigned to an O365 license, check if user exist in OUs. If not, remove the license. 
ForEach ($user in $O365Users)
{
    If (-Not($out -match $user))
    {
       Write-Host "Removing $($user.UserPrincipalName) from Office 365"
       Set-MsolUserLicense -UserPrincipalName $($user.UserPrincipalName) -RemoveLicenses "tenantname:ENTERPRISEPACK"
    }

}

 

 

WSUS maintenance for ConfigMgr

So it was my turn to face problems. I had neglected the obstacle for months excusing myself that everything was still working wonders, until today.

Following screenshot was the reality of my WSUS console when trying to run the server cleanup wizard:

wsuserror

Add so the struggle to solve the problem began and following is the facts and solution:

  • I’m using WSUS running on the internal database in Windows (WID), so I downloaded and installed SQL Server 2014 Management Studio on my server running WSUS
  • Connected to \\.\pipe\microsoft##WID\tsql\query in the Connect to Server window

studioconnecting

  • Ran the following two SQL scripts. My WSUS DB was so bloated that the reindex script from the scripting guys didn’t cut it. When that happens, the deal usually is that you have to delete updates manually directly in the DB.
    Fortunately for me, I found below script to my aid. The script runs the stored procedure EXEC spGetObsoleteUpdatesToCleanup and then deletes the updates. Beware, running these scripts may take several hours depending on the specs of the server and the amount of updates)
  1. DeleteObsoleteUpdates
  2. WSUSreindex

This is a snip of the two scripts showing directly in Management Studio, saved for later use as .sql.

studioscripts

Lesson learned:

Maintaining the SUSDB is important, and is not just something you setup and leave even though running it integrated with ConfigMgr.

**Will update this post on how I’m going to automate this in the future.

How to flash BIOS with SCCM during OSD (Lenovo ThinkPad laptop)

Note: June 3 2018: This post will be updated as soon as possible with some minor changes and reflect how I do this today 🙂

In this blog post I will go into details about how I flash the BIOS of our Lenovo ThinkPad series during OSD using ConfigMgr.

First off you obviously need to download the latest BIOS from the Lenovo support site: http://support.lenovo.com/dk/en/. In this example I’m flashing the BIOS of a ThinkPad T450s.

Go ahead and locate and download the BIOS Update Utility for Windows. The most recent version as of now for T450s is 1.21:

T450BIOS

When downloaded, extract the content to your source file library. In this case I have a folder structure equal to this: D:\Pkgsource\Applications\Lenovo\BIOS\T450S\1.21

The content of the 1.21 folder should be looking like this:

T450BIOS2

Next, mind the highlighted file: FlashBIOS.cmd. Create this file manually with following content (I exit the script with exitcode 0, as the BIOS update itself might return exitcodes seen as failures. Some might dislike this approach, but you can also translate the actual exitcode into zero using whatever method you prefer):

“%~dp0WINUPTP.exe” -s
exit 0

T450BIOS3

With this in place, go ahead and create a package in ConfigMgr with above content and distribute the package to your distribution points (I’m not going into details on this one, as this is pretty standard).

My packages in ConfigMgr looks like this (I have highlighted the package used in this example):

T450BIOS4

Next we will be using the package in our task sequence in a step of Run Command line. This is done somewhere after the step of Setup Windows and Configuration Manager like this (I put BIOS updates in the end of my task sequence as they require reboots):

T450BIOS5

As updating the BIOS to this specific version is a onetime operation, you would want to add following conditions to the Options tab:

T450BIOS6

This will make sure that the step is only run when a Lenovo Thinkpad T450 is being deployed AND when the BIOS is not already the most recent version (no need to run the step again, if the same laptop should be reinstalled in a near future)

You can run following powershell commands to display the computermodel and what BIOS version that currently is installed:

Get-WmiObject Win32_Computersystem

Get-WmiObject Win32_BIOS

T450BIOS7

Enjoy 🙂

Update 1602 for System Center Configuration Manager Current Branch

So, Update 1602 is out for SCCM Current Branch and I just updated my environment.

The new 1602 update is available from within the SCCM console, browsing: Administration > Cloud Services > Updates and Servicing. Right Click the update and select Install Update Pack.

1) Click next on the general page.

1

2) Select the desied features to be included.

2

3) Options for Client Update. I decided to test the new SCCM client on a selected test collection at first.

3

4) Finish the wizard and accept the license terms.

4

5) Go watch CMUpdate.log and wait for following line in the log: INFO: Successfully dropped update pack installed notification to HMan CFD box which translates into installation is complete.

6

Notes from the field:

  • I ran the pre-requisitecheck on the 1602 update before installing. Doing so required me to restart the SMS_EXECUTIVE service on the site server before the actual installation would continue. The status in the console was stuck on Installing, but nothing happened until the restart of the service. (CMupdate.log)
  • I decided to test the new client on a pre-production collection. Doing so actually did that the client binaries wasn’t updated (\\Siteserver\SMS_SITECODE\Client). To update the client binaries, you have to go back to the 1602 update in the console and accept the new client for production in Client Update Options. Yet again, I had to restart the SMS_EXECUTIVE service to see any action in CMupdate.log.

5

 

How to renew Apple Push Certificate for Intune (Hybrid SCCM)

It’s that time of year, where I have to renew my Apple Push Certificate for Intune. And like every other year, I keep forgetting how I did previously.

So now it’s time to put it down in writing. Here goes:

  • First off you have to create a signing certificate. You do that directly in the CM console: Administration > Cloud Services > Microsoft Intune Subscriptions. Click Create APNs certificate request in the ribbon and save the .csr file.

RequestApplePushRibbon

  • Secondly you have to upload the request to the Apple Push Certificates Portal: https://identity.apple.com/pushcert/. Go to the portal and renew your existing certificate.

PushPortal

  • Thirdly, upload the signing certificate (.csr) you just created in the first step and your certificate has been renewed. Download the renewed certificate. This is a file with the extension of .pem; MDM_ Microsoft Corporation_Certificate.pem
  • Finally, go back to your CM console: Administration > Cloud Services > Microsoft Intune Subscriptions. Click Configure Platforms in the ribbon, and select iOS in the dropdown menu. Browse to the location of your .pem file and open it.

IntuneSubProperties

  • Done. The certificate has been renewed

ConfigMgr 1511 – Notes from the field

I just updated my ConfigMgr environment to 1511 (CurrentBranch) and while the installation itself went safe and sound, following is to be noted:

  • The new Software Center never got installed properly with a shortcut in the start menu (%ProgramData%\Microsoft\Windows\Start Menu\Programs\Microsoft System Center\Configuration Manager)
    I had to re-enable the setting in my Client Settings (Disable the feature, OK, Enable the feature, OK and do another policy refresh)

ClientSettings

  • None of the new Windows 10 1511 software updates was synced into SCCM. I checked WSUS manually, and the classification Upgrades was not selected regardless of the Upgrades being indeed selected in SCCM. To solve this, I had to de-select all classifications in SCCM and select them again on the Software Update point. When I checked the chosen classifications in WSUS again, the proper selections was inherited from SCCM as expected and the next sync downloaded the Windows 10 Upgrades.

Classifications

Activate Windows 10 clients with KMS

Looking to activate your shiny new Windows 10 clients with your KMS? This is what you need to do.

1) Install following update on your KMS host: https://support.microsoft.com/en-us/kb/3058168 (Select the OS of your KMS. Reboot is required.)

2) While we are waiting for  Windows Server 2016, MS has created an unique KMS key for the use of activating Windows 10 clients with a Server 2012 R2 key. Browsing your licensing site, you will find a key named like this: Windows Srv 2012R2 DataCtr/Std KMS for Windows 10

3) Install the new key with the usual command: slmgr.vbs /ipk NEWKEYGOESHERE

4) Activate the key using: slmgr.vbs /ato

5) Lean back and watch your W10 clients being activated by your KMS.

 

New PXE deployments: “Skipping Task Sequence because it is not active yet”

I just updated to Windows 10 ADK and was eager to start building my new Windows 10 image.

So I created brand new WinPE10 boot images (x64/x86), deployed them to my DP’s and PXE points. Imported the new OS into SCCM and created my build and capture TS and deployed it to my BuildCapture collection. I booted my VM and noticed my new task sequence wasn’t on the list. I did another reboot just to make sure the new policy was downloaded, but no. Still no W10 build and capture task sequence.

Having a look at the SMSTS.log revealed following: “Skipping Task Sequence because it is not active yet”

Seems like the time is a bit off when deploying with a default available schedule of now. I had to edit the deployment and set the date/time a few days back for the TS to show up. (This is CM 2012 R2 SP1)

 

KB3025417 breaks SCEP reporting (and the solution)

Beginning of June I had my ways with a problem in SCCM/SCEP and the update KB3025417.

I did what I usually do in those situations. I went to the forums, and created following thread: Here!

After fighting with MS 1st line support and not really getting anywhere, then sudden following blog pops up at the ConfigMgr team: Here!

They came up with an alternative solution, which is what I was looking for. However, running W81 x64 and looking to push the mentioned script using ConfigMgr, comes with following obstacles:

  • Packages in SCCM is being launched as a 32bit process. (This is what most people would use, considering that it’s a script and most would use .bat/cmd)
  • The provided script cannot run under a 32bit process. (I learned so the hard way. I confirmed that the script worked when run manually. I took it for granted that it worked as a SCCM package as well – it doesn’t)

So the solution to this is either of following:

  • Use the application model. (Not really prefered in this case, as it requires a detection method)
  • Trick the file x64 redirection to run cmd.exe from %SystemRoot%\Sysnative

An example of the last mentioned solution could be this batch script:

“C:\Windows\Sysnative\cmd.exe” /c “%~dp064bit.bat” (This coming from a x86 process, will run 64bit.bat in a x64 context instead)

64bit.bat will then contain the original script.

No task sequences available – error 80004005

So, I just had a computer denying to have any available task sequences, with the excuse of following error: Failed to get client identity (80004005)

A quick peak into smsts.log was showing below error as well:

NoTaskSequence 

Turns out the date and time in BIOS was off. I corrected the date and time, and all task sequences was available again.