Quantcast
Channel: Michael Niehaus' Windows and Office deployment ramblings
Viewing all 67 articles
Browse latest View live

Troubleshooting Windows AutoPilot: Sample ETW Traces

$
0
0

In yesterday’s AutoPilot troubleshooting blog, https://blogs.technet.microsoft.com/mniehaus/2017/12/13/troubleshooting-windows-autopilot-level-300400/, I showed a variety of captured traces for AutoPilot (and one non-AutoPilot) deployment scenario, which required actually reproducing some different scenarios, including some failure cases.  As some of those aren’t particularly simple to reproduce outside of a lab environment (where you can purposely reconfigure Azure AD or Intune), a few people requested copies of those traces – analyzing the failures without having to cause the failures, as an educational exercise.  So, here they are; download the zip file at the bottom of this blog.

Here’s a quick overview of the included traces, all of which were captured from (unpatched) Windows 10 Enterprise 1709 virtual machines:

  • 1629915.NoAutoPilot.etl.  This trace was captured from a VM that is not known to AutoPilot (hash was never captured or uploaded).  The device went through the standard OOBE process, manually.
  • 1629915.Success.etl.  This is a normal, successful AutoPilot deployment (hash was captured and uploaded, with an AutoPilot profile of settings applied).  The device went through the optimized OOBE process.
  • 1629915.801C0003.etl.  This trace, from the same VM as the success case, shows what happens when the user does not have the ability to join Azure AD.
  • 1629915.801C0003-5limit.etl. This trace, also from the same VM as the success case, shows what happens when the user can join no additional machines to Azure AD (device limit was set to 5 in Azure AD, this would have been device #6).  (From what I can tell, this trace is identical to the previous one, which just indicates that there is no way to tell the difference between the two failure scenarios.)
  • 1629915.80180018.etl.  This trace, also from the same VM as the success case, shows what happens if you take away the Azure AD Premium or Intune license from the user who was setting up the device.  (They did again have rights to join Azure AD.  I only captured one trace, even though I did run through both scenarios separately – once I saw that “no AAD Premium license” and “no Intune license” returned the same error, I didn’t bother capturing a second trace.)

Let me know if you find any other interesting tidbits in these traces.

AutoPilotTraces


Windows AutoPilot Azure AD Branding

$
0
0

When you use Windows AutoPilot to deploy new devices, you want the process to be friendly and familiar for the users going through the process.  One of the ways that is done is by customizing the logon experience to include logos and company-specific text.  This leverages an Azure Active Directory Premium feature called company branding, describe at https://docs.microsoft.com/en-us/azure/active-directory/customize-branding.  The basic steps:

  • Sign into the Azure Portal as a tenant admin.
  • Navigate to Azure Active Directory –> Company branding.
    image
  • Click Edit to configure the needed settings.
    image
  • Fill in all the customizations.
    image
    image

You will need some bitmaps to do this:

  • A square logo, 240 pixels by 240 pixels, PNG or JPG, 10KB or smaller.
  • A banner logo, 280 pixels by 60 pixels, PNG or JPG, 10KB or smaller.
  • A background image, 1920 pixels by 1080 pixels, PNG or JPG, 300KB or smaller.

If you need to resize existing bitmaps, or reduce the size of existing bitmaps by reducing the color pallet, you may need to use something like Paint.NET.

So then you just need to figure out where those values are used, so let’s look at the resulting Windows AutoPilot screen captures:

image

image

So let’s look at the mapping from each of the highlighted and numbered items in the screenshots above:

  • (1) and (5) correspond to the “square logo image” (240x240px).
  • (2) and (3) don’t come from the company branding.  Instead, you can set that value in the “Name” field of the Azure AD tenant properties:
    image
    (Watch out if you include special characters in the text, e.g. accented characters, as they may not display properly.  That’s being investigated.)
  • (4) and (6) come from the “sign-in page text” field.  (You might notice a bug in the above screenshot:  The text, which can be up to 256 characters, wraps on the username screen, but not on the password field.  I’ll check on getting that fixed.)
  • Notice that the “user name hint” property specified in AAD is ignored.  (I’ll check on that too.)

Some of you might have noticed a different password screen too.  If you are using ADFS, you’ll be presented with a web view to specify the password (since it’s the ADFS servers verifying the password for Azure AD).  ADFS has its own customization capabilities, described at https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/operations/ad-fs-user-sign-in-customization, which includes this useful sample:

AD FS customization

Also note that you can have Intune present a “terms and conditions” page (presented in a web view as part of the MDM enrollment process).  See https://docs.microsoft.com/en-us/intune/terms-and-conditions-create for details on how to set that up.

Changing the Hyper-V screen resolution during OOBE

$
0
0

I’ve recorded a variety of videos (especially for Windows AutoPilot, but prior to that for other Windows deployment scenarios) that involve capturing the initial phases of a Hyper-V VM’s boot process.  Normally, these default to a resolution like 1024x768, although they can be changed to a better resolution (e.g. 1366x768 or 1920x1080) manually after Windows has started up.  The end result is a rather “square” image:

image

But what if you want the entire video to be fixed at a particular resolution?  If you are running Hyper-V on Windows 10 or Windows Server 2016, there is an easy way to do this using the Set-VMVideo PowerShell cmdlet.  First, let’s try switching to 1366x768:

PS C:\> Set-VMVideo -VMName Demo -ResolutionType Single -HorizontalResolution 1366 -VerticalResolution 768

The result (effective the next time the VM starts up):

image

The "-ResolutionType Single” is required in this case to force the VM to a specific resolution by telling Windows that is the only supported video resolution.  (And yes, OOBE does add black bars to left and right.)

You can also change to 1080p (1920x1080) the same way:

PS C:\> Set-VMVideo -VMName Demo -ResolutionType Single -HorizontalResolution 1920 -VerticalResolution 1080

with this result (yes, more and bigger black bars from OOBE):

image

You may still see the VM start up with a smaller resolution and then switching to a higher resolution a second or two later.  There’s no easy way around that, but if you set the VM to be full screen (e.g. using a 1080p monitor) and then capture a video from that monitor, you don’t notice the switching.

If you want to change the VM back to its original, default behavior, you can:

PS C:\> Set-VMVideo -vmname Demo -ResolutionType Default

Afraid of Windows 10 with Azure AD join? Try it out (part 1)

$
0
0

I’ve been surprised by the number of organizations that have never tried to join a Windows 10 device into Azure Active Directory.  So let’s spend some time talking about that.

You’ve been able to join a Windows device to Active Directory domains for as long as there have been Active Directory domains.  With Windows 10, there is now the ability to join Azure Active Directory.  Azure Active Directory is a multitenant directory, so you aren’t joining a domain, you’re joining a tenant.  And most of your organizations already have such a tenant, since it’s used by Office 365, Intune, Azure services, and many other things.  More reading if you want to know more:

And a couple of things that Azure AD is not:

  • It’s not Active Directory running in the cloud.  (We do provide a service like that, called Azure Active Directory Domain Services, designed for scenarios where you want to join Azure VMs into an AD domain.  It’s not designed for on-prem PCs or servers.  And yes, that’s a confusing name.)
  • It’s not for device management.  (To manage devices joined to Azure AD, you would use Intune or another MDM service, potentially combined with System Center Configuration Manager via co-management.)

To confuse matters a little more, there is one more scenario to discuss called Hybrid Azure Active Directory Join.  Why is this confusing?  Well, the device is joined to Active Directory (just like most of you do today), so it has access to all the AD features (e.g. GPOs).  If you look at the Settings app, you won’t see anything about Azure AD.  For all intents and purposes, it behaves just like an AD-joined device (because it is), with a few extra benefits.  For the purposes of this blog post, we’ll ignore this scenario because we want to focus on devices that are joined directly to Azure AD, and users who sign on using Azure AD credentials, with no need for any domain controllers or any other on-prem resources.

Setup

Let’s shift focus then to setting all of this up.  I performed the following tasks:

  • Using my MSDN Azure subscription, I created a new Azure AD tenant called “autopilotrocks.onmicrosoft.com” and added a cloud-only admin account to it, admin@autopilotrocks.onmicrosoft.com (used later).
  • Using my GoDaddy account, I created a new “autopilotrocks.com” DNS domain, then added it as a custom domain to the Azure AD tenant.  (You don’t have to do this, but it’s much nicer to sign on with @autopilotrocks.com instead of @autopilotrocks.onmicrosoft.com.)
  • I created a new Windows Server 2016 domain controller for “autopilotrocks.com” (the AD domain/forest).  (I made this a DHCP server on its own private Hyper-V network, and connected it to an RRAS server for routing to the internet.  Internet connectivity is needed.)  I created a new domain account, Michael, so that I have an account to use later.
  • I download, installed and configured AAD Connect to sync my AD domain to AAD, setting up Pass-Through Authentication to make things simple.  (Setting up ADFS is a fair amount of work.)  The click-by-click:
    image
    I won’t use express settings because I want to see the options available:
    image
    Nothing I want to customize here:
    image
    A few pre-reqs get installed:
    image
    Then other configuration is done:
    image
    Now I can choose Pass-Through Authentication:
    image
    And specify my cloud admin account:
    image
    Then I can click to add my AD domain:
    image
    And specify the domain admin details (because I’m too lazy to create a separate account):
    image
    I then clicked “Next” through the remaining screens, and then confirmed on the final screen by clicking Install:
    image
    And finally, done:
    image

Total elapsed time: about two hours.  Total cost: $12.17 to register the new autopilotrocks.com domain name – there are no Azure costs at all.

One final piece worth pointing out:  By default, all accounts have rights to join devices to Azure AD.  That can be changed if you want via the Azure portal (but if you are planning to use Windows AutoPilot, I wouldn’t change the default):

image

Adding a device

So now on to the next piece:  Joining a device into Azure AD.  As I mentioned before, there are three ways of doing this.  Since you’ve already shown some patience by reading this far, we might as well walk through all three.

1. Join from OOBE

After clicking through the first few screens in OOBE, you are asked to specify Azure AD credentials:

image

Note that in this case the machine didn’t ask if this was a work or home machine, because I’m using the Enterprise SKU.  (It also won’t ask if it finds that this device is registered with AutoPilot.  But this device isn’t registered with AutoPilot – at least not yet.)

I can type in my Azure AD account that I created earlier in AD and synced with AAD Connect into Azure AD:

image

and then I can type in my password, which is automatically validated against my AD domain controller using Azure AD Pass-Through Authentication (woo-hoo, works great).  After a few more OOBE screens, the device is joined and the user is automatically signed on.  Once at the desktop, you can see in Settings that the device is joined to Azure AD:

image

(Notice how there is no “Info” button?  That’s a sign that this device isn’t MDM-managed.)  It’s also interesting to look at this from a command prompt using “dsregcmd.exe /status”:

image

2. Join from Settings

If you have an existing install with a device that’s using a local account in a workgroup, or an MSA, you can join the device to Azure AD through the Settings app.  Navigate to Accounts –> Access Work or School and then click the Connect button:

image

While you might be tempted to type in the user ID (e-mail address), that would just “add a work account” – that’s not the same as Azure AD join.  To do the Azure AD join, click the link lower on the wizard pane that says “Join this device to Azure Active Directory”:

image

Then type in the user ID (e-mail address):

image

and password:

image

A confirmation is needed:

image

And then we’re done:

image

We can see the end result is exactly the same as doing this via OOBE:

image

3. Join via a Provisioning Package

I’m going to cheat for this one and recycle some older screenshots from Windows Configuration Designer.  To create a provisioning package to join Azure AD, you need to choose Azure AD (obviously):

image

Then you can click “Get Bulk Token” which will ask for Azure AD credentials:

image

image

The token (which can be used for up to 30 days to join an unlimited number of devices to Azure AD) is returned from Azure AD and stored in the provisioning package.  Install that provisioning package on the device in one of the supported ways:

  • Inject it offline using DISM, before the OS boots for the first time.
  • On the first OOBE screen, press the Windows key five times (really) and browse to a USB key that contains the provisioning package.
  • Manually install the provisioning package via Settings:
    image
  • Install the provisioning package using PowerShell (using the Install-ProvisioningPackage cmdlet).
  • Install the provisioning package by double-clicking on it and acknowledging the prompts.

Once installed, you can see the same views via Settings or from the DSREGCMD /Status command that we looked at previously.

Limited-Time Offer

Want to try this out yourself?  Send me an e-mail at mniehaus@microsoft.com and I’ll send you a user ID and password that you can use to join a device into my Azure AD tenant.  (There’s no MDM in place, and I reserve the right to accidentally or purposely remove the device – no a big deal since you probably won’t find a device joined to my tenant to be very useful.)

Summary

Thanks for reading this far.  You’re probably thinking “how can there possibly be a part 2” after all of this, but there certainly will be (and needs to be).  It might take me a little while to finish the next one, but stay tuned.

Starting a new chapter

$
0
0

When I originally accepted a job with Microsoft, just over 14 years ago, I chose the company because of the sheer number of different roles that were available – lots of opportunities for new challenges.  That has taken me through roles that included consulting, development, program management, product marketing, and product management.

Starting this week, I have changed roles again, moving from Windows commercial product marketing (which covered the product marketing and product management roles above) to the Windows & Devices Group (WDG), the group that creates Windows, as a principal program manager on the modern deployment team that works on Windows AutoPilot, MDM management, subscription activation, and related technologies.

While that will likely change the typical makeup of my day quite a bit, there will certainly be areas that won’t change:  You’ll still see me blogging (something that wasn’t in my previous job description either), participating in events (talking about modern deployment and management – someone else can talk about Windows as a service), working with customers, MVPs and partners, working with various product groups to address enterprise concerns, etc.  And I’ve been contemplating some new things, e.g. podcasts, videos, and that sort of thing.  So I’m definitely not going to disappear.

The last five years in Windows commercial marketing were a lot of fun, filled with plenty of successes and a fair number of failures too.  Now I’m looking forward to the path ahead.

As always, feel free to reach out to me via e-mail (mniehaus@microsoft.com), Twitter (@mniehaus), or LinkedIn (http://www.linkedin.com/in/mniehaus/).  And keep deploying Smile  Now, back to work…

 

p.s. If you send me a LinkedIn request, introduce yourself, describe how you know me, explain what you do, etc. -- one downside of having a "director of marketing" title (my old job) is that you get lots of requests from people who want to sell you things.  So if I don't recognize you and just see a generic connection request, I'm likely to ignore the request.

Afraid of Windows 10 with Azure AD join? Try it out (part 2)

$
0
0

In the part 1 blog, I talked about the mechanics of joining Windows 10 devices to Azure AD.  Now let’s shift focus and talk about the impact of doing it.  I already mentioned that Azure AD doesn’t provide management capabilities (those should be provided via Intune, System Center Configuration Manager, or other management tools).  But what about authentication with existing on-prem resources like web servers, file servers, etc.?  That’s the focus for this post.

Baseline:  AD-joined

Let’s start with the basics, things that you expect to “just work” because of Active Directory: users in AD, signed into devices joined to AD, accessing resources in AD.  Behind the scenes, Windows 10 talks to an AD domain controller to get a Kerberos TGT (ticket-granting ticket), which can then be used to access AD-joined resources.  No big surprise, these work just fine:

  • Access a UNC path on an AD member server.
  • Access a AD member web server configured for Windows integrated security
  • Running Active Directory Users & Computers to administer all AD objects
  • Running DHCP snap-in to administer an AD-joined DHCP server

So, let’s then look at another scenario:  Using the same AD-joined servers, let’s try using an Azure AD-joined device, where the user is signing into the device using an Azure AD account that has been synchronized with the AD domain.  What do you expect to happen in that case?  Before answering that question, let’s dig in a little deeper on what happens when you sign into an Azure AD-joined device.  Instead of talking to an AD domain controller, it talks to the Azure AD service, which provides a PRT (Primary Refresh Token), which can then be used to access Azure AD-protected resources. 

Next Step:  Azure AD-joined

But what about AD-joined resources being access from an Azure AD-joined device?  The PRT doesn’t do any good in that case, because AD doesn’t know anything about it.  So to make this work, Windows 10 performs an extra step: When it sees that it is on a network with an available AD domain controller, it reaches out to that server to get a Kerberos TGT.  So now it has everything it needs to access both: a PRT for Azure AD, and a TGT for AD. 

But how does this work? Through the magic of Azure AD Connect, Windows knows the AD domain name (synchronized from the on-prem AD into Azure AD) and can use that to look for an AD domain controller.  When it finds an AD domain controller, it can they get the TGT  needed to access AD-joined resources.  Let’s look at the results:

  • Access a UNC path on an AD member server
    • Works perfectly.
  • Access a AD member web server configured for Windows integrated
    security
    • Works perfectly.
  • Running Active Directory Users & Computers to administer all AD
    objects
    • You have to manually specify the domain that you want to connect to, as the MMC snap-in can’t use LDAP to figure that out itself.  Just use "Change domain” and then it will work perfectly.
  • Running DHCP snap-in to administer an AD-joined DHCP server
    • You may need to specify the DHCP server name or address (may work automatically if you used another AD-linked MMC snap-in first), but once you do it will work perfectly.

No surprises, you can successfully authenticate, although you might need to help some tools locate the AD domain you are trying to administer or the resource you are trying to access (if it’s located using AD).

Another Twist:  Windows Hello for Business

By default, devices joined to Azure AD will be enabled for Windows Hello for Business, which enables devices to sign on using a PIN or biometrics.  (You can turn it off via MDM policies, but you’re not doing your users any favors by doing so – avoiding passwords is a great thing.)  This works well when accessing only Azure AD resources, but does have some implications when accessing AD-joined resources.

For me, this was definitely a learning experience, pouring over the Windows Hello for Business documentation, including a detailed deployment guide.  I could probably write several blogs about that, but I’ll just provide the cliff notes here:

  • You want to do a “hybrid” deployment of Windows Hello for Business.
  • There are two choices for setting this up:
    • Key trust, which requires at least one Windows Server 2016 DC, Certificate Services set up in the domain, Kerberos certificates on each DC, the trusted root cert deployed to each device using Intune, and an accessible certificate revocation list (CRL).
    • Certificate trust, which needs the Windows Server 2016 schema, but works with older DCs.  But for this to work, you need to issue certificates to everyone, which requires NDES, more Intune configuration, deploying the trusted root cert, and having an accessible CRL.  (You’ve probably already done this work if you are using smart cards, so it might not be so bad).

Once you have either a key trust or certificate trust set up and properly configured (took me several days to get the CRL right), then all the above tests work just as they did without Hello for Business:

  • Access a UNC path on an AD member server
    • Works perfectly.
  • Access a AD member web server configured for Windows integrated
    security
    • Works perfectly.
  • Running Active Directory Users & Computers to administer all AD
    objects
    • You have to manually specify the domain that you want to connect to, as the
      MMC snap-in can’t use LDAP to figure that out itself.  Just use "Change
      domain” and then it will work perfectly.
  • Running DHCP snap-in to administer an AD-joined DHCP server
    • You may need to specify the DHCP server name or address (may work
      automatically if you used another AD-linked MMC snap-in first), but once you do
      it will work perfectly.

More Options Available

Also note that you might choose to leverage something like the Azure AD Application Proxy to access internal web apps.  With that, you can authenticate using Azure AD (including support for multi-factor authorization) and let Azure handle the internal authentication and redirection for you (no client-side VPN required).  And as announce last week, you can now configure these apps using PowerShell; see https://cloudblogs.microsoft.com/enterprisemobility/2018/02/15/faster-application-deployment-in-azure-ad-application-proxy/ for more details.

Summary

For those afraid of joining devices to Azure AD because of the number of Active Directory-secured apps, services, shares, etc. that are being used in your environment, I think you’ll be presently surprised at how well it can work.  Obviously your results may vary (people always find creative ways to configure things, so there’s definitely a chance that some apps might not work, at least not without some reconfiguration), so you still want to do some testing on your own.  But it will likely work well enough for you to try it out yourself – take a few devices, maybe even your own primary device, and join it to Azure AD to see what happens.  (See part 1 for more details on that.)

What’s Changed in MDT 8450

$
0
0

Back in December, a new build of MDT was released.  Continuing the pattern established with the release before it (8443), it’s identified only by its build number, hence it’s called MDT 8450.  As Aaron detailed in the announcement blog at https://blogs.technet.microsoft.com/msdeployment/2017/12/21/mdt-8450-now-available/, this release is primarily for compatibility with the latest ADK, Windows 10, and ConfigMgr releases, and includes fixes for a variety of bugs (with the full list included).

Here’s a quick rundown of every change made to the MDT scripts and templates for those that are curious:

  • Templates:
    • SCCM_Client.xml.  Changed the UEFI recovery partition size from 300MB to 499MB to make sure it’s big enough (same as what MDT was already using for Lite Touch).
    • SCCM_Server.xml.  Changed the UEFI recovery partition size from 300MB to 499MB to make sure it’s big enough (same as what MDT was already using for Lite Touch).
  • Scripts:
    • DeployWiz_ProductKeyVista.vbs.  Fixed logic that caused an “invalid deployment type” error.
    • LiteTouch.wsf.  Fixed a variety of logic related to LTI Windows 10 upgrade task sequences (which also fixed an issue related to autologon after a reboot prior to the upgrade).
    • LTIApply.wsf.  Changed the BCDBOOT logic to always run it the same way for UEFI devices, regardless of the OS version, to address some boot-loop issues on bare metal UEFI deployments on some devices.
    • LTICleanup.wsf.  Inconsequential changes (line alignment).
    • ServerManager.xml.  Fixed component names that prevented the installation of Windows Media and IIS Management Console features on Windows Server 2016.
    • SetupComplete.cmd.  Fixed logic related to the changes in LiteTouch.wsf for Windows 10 upgrade task sequences.
    • SetupRollback.cmd.  Ditto.
    • ZTIBde.wsf.  Changed the BitLocker pre-provisioning logic to not try to do anything with the TPM while in Windows PE, to avoid putting the TPM into a reduced functionality state.
    • ZTIGather.wsf.  Added some new chassis types (30, 31, 32 for laptops; 35 and 36 for desktops; 28 for servers).
    • ZTIMoveStateStore.wsf.  Fixed the logic that moved the state store so that it didn’t use a hard-coded \StateStore folder location.
    • ZTIOSRole.wsf.  Fixed the logic so that it works for multiple calls to get the source location.
    • ZTIUtility.vbs.  Fixed logic to ignore disabled “Install Operating System” steps (caused problems with some types of task sequences).

Additionally, all the standalone task sequencer binaries (used to run LTI task sequences) were updated to the latest code from ConfigMgr.

So, it’s a very minor update overall.  If you have existing task sequences created with MDT 8443, you shouldn’t need to recreate them, although if you have ConfigMgr task sequences you might want to edit the “Format and Partition” UEFI steps to specify 499MB instead of 300MB for the recovery partition size.

And as always, back up your deployment share before upgrading (especially if you’ve made any script edits), reintegrate your changes if needed, and make sure you update your boot images (including on WDS, USB boot media, boot ISOs, etc.) as mismatched versions will cause all sorts of problems.

More on included Windows 10 apps

$
0
0

I’ve stated this publicly a few times, but many people don’t realize the distinction so I’ll repeat it again here.  There are provisioned apps included in Windows 10 (that you can remove, see https://blogs.technet.microsoft.com/mniehaus/2015/11/11/removing-windows-10-in-box-apps-during-a-task-sequence/) and there are apps that are installed from the Microsoft Store when you first sign in (that you can prevent from installing on some SKUs, see https://blogs.technet.microsoft.com/mniehaus/2015/11/23/seeing-extra-apps-turn-them-off/).  For example, Weather is a provisioned app that you can remove; Network Speed Test is an app that comes from the store when the user signs in.

The documentation team has an article at https://docs.microsoft.com/en-us/windows/application-management/apps-in-windows-10 that has the current list of provisioned (in-box) and installed (from the store on first logon) for various Windows 10 releases.  But one thing that isn’t reflected in that documentation:  the list of apps installed from the store can be different depending on the type of account you sign in with, by the SKU that you are using, and even by the region of the world the device is in.

This is what the default start menu layout looks like in all Windows 10 1709 SKUs:

image

Each of those down-arrow icons will be replaced by an app from the store (some of which are actually installed from the store, some of which are just “shortcuts” that will trigger the installation if you launch them), after the user signs in for the first time.

So let’s do a little comparison.  First, let’s look at a local account being used on Windows 10 Pro 1709:

clip_image002

OK, very consumer-y, with lots of games.  Now, let’s look at a local account signing into Windows 10 Enterprise 1709:

clip_image002[5]

Much better – no games, with most of the apps focused more on productivity.  And signing into Windows 10 Enterprise 1709 with a Microsoft Account, an Active Directory account, or an Azure Active Directory account yields the same result.

But on Windows 10 Pro 1709, you will see a different result when you sign in with an Active Directory account or an Azure Active Directory account.  They will look the same as Windows 10 Enterprise 1709:

clip_image002[7]

So a quick summary: You’ll get games on Windows 10 Pro 1709 only when using local or MSA accounts; you’ll never get games for AD or AAD users, or for anyone on Windows 10 Enterprise.

Also note that Windows 10 Pro for Workstations will soon have the same behavior as Windows 10 Enterprise, as described in the Windows Insider blog:

Productivity focused out of box applications: In the Windows 10 Fall Creators Update, the out of box experience for Windows 10 Pro for Workstations draws from the Pro edition of Windows 10. One area where this is noticeable is the suite of applications installed out of the box visible as tiles in the start menu. In the next release for Windows, you will see for Windows 10 Pro for Workstations productivity and enterprise focused applications in place of consumer applications and games. This was one of the top feedback shared with us by our partners and users and we’re delivering this in our next update.

Also note that on Windows 10 Enterprise, you can turn off the installation of apps from the store altogether by configuring the “Turn off Microsoft consumer features” GPO or the equivalent MDM policy.


ConfigMgr task sequences from the internet

$
0
0

After some campaigning and some quick work from the ConfigMgr team for the ConfigMgr tech preview 1802 release, you can now use non-OSD task sequences, such as those that install apps or perform feature updates, even for internet-connected (and Azure AD-joined) devices.  See https://docs.microsoft.com/en-us/sccm/core/get-started/capabilities-in-technical-preview-1802#windows-10-in-place-upgrade-task-sequence-via-cloud-management-gateway for more details.

Here’s a snapshot of what that looks like, first showing an internet-connected client (connecting through the ConfigMgr cloud management gateway) running the TP1802 client (build 8627):

image

And then the view in Software Center:

image

where you can see the task sequence named “Non-OSD Task Sequence” (just to be clear, that’s what I named it).  And all I had to do to get that to show up (after setting up the cloud management gateway and installing TP1802) is to check the “Allow task sequences to run for client on the internet” box:

image

And if you look back at the Software Center picture above, you can also see another new feature in TP1802 too: It’s showing apps that target users, even on this Azure AD-joined device.  That feature is described at https://docs.microsoft.com/en-us/sccm/core/get-started/capabilities-in-technical-preview-1802#use-software-center-to-browse-and-install-user-available-applications-on-azure-ad-joined-devices.

So in a short period of time, ConfigMgr has gained some important new capabilities for Azure AD-joined devices, which will be very useful for Windows AutoPilot deployments.

Printing to on-prem printers from Azure AD-joined devices

$
0
0

Since most of us have been using Active Directory for ages, you probably also take for granted the process for printing to your on-premises printers:  They are published to Active Directory, you can search for them, and you can easily connect to them.  But what happens when you join your devices to Azure AD instead?  As discussed in https://blogs.technet.microsoft.com/mniehaus/2018/02/21/afraid-of-windows-10-with-azure-ad-join-try-it-out-part-2/, you can certainly connect to a Windows Server (AD-joined) hosted print queue if you know its UNC path (authentication works via a Kerberos ticket).  But how do you discover that printer in the first place?  The low-tech approach is to label the printer with its UNC path, so you just walk up to it, read the UNC, and type it in.

Fortunately, we’ve released a higher-tech approach that solves two different problems:

  • Discovering Windows Server-hosted printers from Azure AD-joined devices
  • Printing to those printers from anywhere in the world

This solution is called Hybrid Cloud Printing because it connects those Azure AD-joined devices to your existing Active Directory-joined Windows Server printing infrastructure.  That was announced back in February via the Enterprise Mobility blog.  As you can probably guess from the diagram included in that blog, there are a few components in the solution:

First, some requirements:

  • Windows 10 1703 (Creators Update) or higher.
  • Windows Server 2016 on your print servers.
  • An Azure AD tenant.
  • Azure AD Connect, to synchronize your Active Directory with Azure AD.
  • An MDM service, e.g. Intune, to configure the print settings on each device.

Then, you need to set it up.  To make the connection from internet-facing Azure AD-joined devices to those on-prem Windows Server 2016-hosted services, Azure Application Proxy is used.  This makes an outbound connection to Azure, which is used to then allow inbound traffic to the published services.  There are two ways this can be set up:

  • Azure Active Directory pre-authentication, where Azure AD makes sure the user is authenticated before the traffic passes through the proxy.
  • Passthrough authentication, letting Windows Server authenticate the users via Kerberos.

Typically the first option is recommended, to support things like conditional access and multi-factor authentication.  I recommend sticking with that that recommendation, following the “five” steps at https://docs.microsoft.com/en-us/windows-server/administration/hybrid-cloud-print/hybrid-cloud-print-deploy:

  1. Install Azure AD Connect to sync between Azure AD and AD.  I covered that in https://blogs.technet.microsoft.com/mniehaus/2018/01/19/afraid-of-windows-10-with-azure-ad-join-try-it-out-part-1/.
  2. Install the Cloud Print package on the print server.
  3. Install the Azure Application Proxy.
  4. Configure the MDM policies.
  5. Publish desired shared printers.

Since each of those steps includes multiple sub-steps, it’s really more like a 20-25 step process.  And initially I walked through all of those steps – and it didn’t work at all.  Fortunately, one of the ConfigMgr/Intune MVPs, Sandy Yinghua, has a blog that documents how she did it.  I used those steps to verify my configuration and with that was able to get everything working.  I would note that I did things a little differently:

  • I didn’t use a custom internet URL (mcs.smsboot.com in her example) for the Azure App Proxy-published websites.  Instead, I used the generated msappproxy.net URLs because then I didn’t need additional certs.
  • I did get a public cert for my print server, so that I didn’t need to distribute a trusted root cert to the client machines when they talk to the print server via the Azure App Proxy.  Self-signed certs aren’t any fun (although Intune has no issues deploying them, so it wouldn’t be that bad).

But otherwise, my setup matches.  Here are the device configuration settings I configured in Intune:

What those look like in Intune:

image

And here are a few commands that I used as I was experimenting with the printer publishing process:

Publish a test printer

Publish-CloudPrinter -Printer EcpPrintTest -Manufacturer Microsoft -Model FilePrinterEcp -OrgLocation '{"attrs": [{"category":"country", "vs":"USA", "depth":0}, {"category":"organization", "vs":"AutoPilotRocks", "depth":1}, {"category":"site", "vs":"Redmond", "depth":2}, {"category":"building", "vs":"109", "depth":3}]}’ -Sddl "O:BAG:SYD:(A;;LCSWSDRCWDWO;;;S-1-5-21-501278528-1731656756-2472999879-1114)(A;OIIO;RPWPSDRCWDWO;;;S-1-5-21-501278528-1731656756-2472999879-1114)(A;OIIO;GA;;;CO)(A;OIIO;GA;;;AC)(A;;SWRC;;;WD)(A;CIIO;GX;;;WD)(A;;SWRC;;;AC)(A;CIIO;GX;;;AC)(A;;LCSWDTSDRCWDWO;;;BA)(A;OICIIO;GA;;;BA)" -DiscoveryEndpoint https://clouddiscoveryproxy-autopilotrocks.msappproxy.net/mcs -PrintServerEndpoint https://cloudprintproxy-autopilotrocks.msappproxy.net/ecp -AzureClientId 23772c3e-1a3b-4f28-86f9-ec614a53a776 -AzureTenantGuid 0b458c6e-97ce-4c7e-bc5e-1d29552989a5

Query published printers

Publish-CloudPrinter -Query -DiscoveryEndpoint https://clouddiscoveryproxy-autopilotrocks.msappproxy.net/mcs -AzureClientId 23772c3e-1a3b-4f28-86f9-ec614a53a776 -AzureTenantGuid 0b458c6e-97ce-4c7e-bc5e-1d29552989a5

Unpublish a printer

Publish-CloudPrinter -Unpublish -Printer EcpPrintTest -DiscoveryEndpoint https://clouddiscoveryproxy-autopilotrocks.msappproxy.net/mcs -PrintServerEndpoint https://cloudprintproxy-autopilotrocks.msappproxy.net/ecp -AzureClientId 23772c3e-1a3b-4f28-86f9-ec614a53a776 -AzureTenantGuid 0b458c6e-97ce-4c7e-bc5e-1d29552989a5

Trying it out

Let’s look at the client experience then.  The first sign of something different is on the “Printers & scanners” page in Settings.  There is a new “Search for cloud printers” link:

image

When you click that, you can then browse from a list of available locations, presented in a hierarchy that you can define:

image

And you can search for printers by keyword (or just leave the keyword blank to get all printers in that location):

image

And finally, select the printer and click “Add device” to add it:

image

Finally, I have a printer, with a slightly different icon to show that it’s a cloud printer:

image

And printing works, from any internet-connected location (thanks to the Azure Application Proxy).  The particular “printer” in this case is useful for testing, as it doesn’t waste any paper:  It just drops an XPS file into a folder on the server.

image

Check out the Ignite 2017 video at https://www.youtube.com/watch?v=Bvt1L--lqE4 for more information.  And with any luck, this will be integrated into Windows Server 2019 and easier to set up.

Managing Windows AutoPilot devices using the Intune Graph API

$
0
0

A while back, I published a sample script called Get-WindowsAutoPilotInfo, which is designed to help define existing computers with the Windows AutoPilot deployment service, See https://blogs.technet.microsoft.com/mniehaus/2017/12/12/gathering-windows-autopilot-hardware-details-from-existing-machines/ for more details about that.

Some people have asked to take this one more step, to automate the process of uploading the gathered hardware details.  Fortunately, this can be done using the Intune Graph API (exactly what the Intune portal uses behind the scenes).  To show you how to do that, I’ve published a sample PowerShell module called WindowsAutoPilotIntune on the PowerShell Gallery.  Here’s an overview of how to use it:

Install the needed modules

There are two modules needed, the WindowsAutoPilotIntune module and the AzureAD module that it uses for authenticating with Intune.  These can both be installed using the Install-Module PowerShell cmdlet:

Install-Module AzureAD
Install-Module WindowsAutoPilotIntune

Here’s what that looks like:

image

Then we can exercise it a little by getting a list of the devices that have already been uploaded.  First, load the module and connect to Intune by first specifying the user to use:

Import-Module WindowsAutoPilotIntune
Connect-AutoPilotIntune

image

After specifying the user principal, you’ll be prompted for a password (and if this is the first time you’ve used the Intune Graph APIs, you’ll also be prompted for permission).  Make sure you specify a user that has sufficient rights.  (Note that the authentication will time out after a period of time – the Azure AD sign-in process generates an access token that only has a limited life.)

image

Then you can get a list of devices:

Get-AutoPilotDevice

image

So let’s try something a little more involved: Adding some new devices.  I’ll start with a CSV file created with the previously-mentioned Get-WindowsAutoPilotInfo script.  It has five machines in it, one of which have already been imported (to show what an error looks like):

Import-AutoPilotCSV -csvFile C:\Demo.csv

image

As each device is added to Intune, each new object created in Intune is returned and displayed.  But that doesn’t mean that they are immediately added to the AutoPilot deployment service.  Instead, Intune takes care of this as a background process running asynchronously.  We can check on the progress to see if it is done yet, and once it is done we can see if the devices were added successfully.

image

The script keeps checking every couple of seconds, and shows you the number of devices that are still being worked on.  It looks like there is no progress being made, but then all complete at the same time (all part of the same batch).  Once all the devices are done, the final status is retrieved and displayed, and as we can see 4 devices were added successfully, while one had a 640 StorageError (which in this case means the device is already registered).

One final step is performed after the final status is retrieved: an object for each device is deleted, leaving just the four new devices, which can be seen with the original Get-AutoPilotDevice cmdlet.

Check out the Import-AutoPilotCSV function to see a few other functions that are used to complete this task:

  • Get-AutoPilotImportedDevice, which retrieves the status objects for each device being added.
  • Add-AutoPilotImportedDevice, which adds the device.  (Notice that you can specify an order ID for these devices, which could be useful for grouping devices using dynamic Azure AD device groups.)
  • Remove-AutoPilotImportedDevice, which removes the status objects once the processing is complete.

Notice that there is no function to remove the added devices.  Just like in the Intune portal, there’s no way to do this yet – you can remove the device via the Microsoft Store for Business, but you’ll still see it in Intune.  That’s still being worked on.

As always, the PowerShell module is provided as an example, provided as-is with no warranty or support, and could easily have bugs. See the Intune Graph API documentation for more details on the REST calls being leveraged, and the PowerShell Intune Samples on GitHub for more on interacting with Intune via the Graph API. 

Let me know via comments on this blog, via Twitter (@mniehaus), or via e-mail (mniehaus@microsoft.com) if you are planning to use this, as we’re interested in understanding the scenarios you might be considering.

Cleaning up apps to keep Windows 10 sysprep happy

$
0
0

As we documented at https://support.microsoft.com/en-sg/help/2769827/sysprep-fails-after-you-remove-or-update-windows-store-apps-that-inclu, sysprep will fail when creating a custom Windows 10 image if there are any apps installed during the image creation process that aren’t also provisioned in the OS.  Depending on how you create your image, this can be problematic because during the process (typically an MDT or ConfigMgr task sequence), the Microsoft Store can download and install stuff from the internet.  And when that happens, you’ll see error messages logged by sysprep (which you can find in the C:\Windows\System32\Sysprep\Panther\Setupact.log file) like this:

SYSPRP Package Microsoft.MicrosoftOfficeHub_17.8830.7600.0_x64__8wekyb3d8bbwe was installed for a user, but not provisioned for all users. This package will not function properly in the sysprep image.

The longer your image creation process takes, the more likely such a failure is.  That also means this failure can be sporadic: sometimes you’ll sysprep before the Store installs updates, other times you won’t.

So how do you fix this?  My favorite way:  Don’t build your images on a VM that has internet access, since there’s no way the Microsoft Store can download any apps when there is no internet connectivity.  Or you can try to purposely disable internet access, using something like Brandon’s blog.

But if you want to have internet access or need internet access, there are other ways.  You can follow Johan’s blog, which leverages existing Group Policy settings (which are a little tricky to set on a workgroup machine when creating an image, but there are scripts to help with that).  Or you can add an extra step to the task sequence to clean up the offending apps prior to running sysprep.  Just to see how hard that would be, I decided to try it – turns out it’s not that bad.

But first, let’s set up a repro.  The easiest way to do that is to add a step to an MDT task sequence to suspend the task sequence.  Then you can launch the Store, force the installation of app updates, install other apps (I installed Facebook manually for good measure), etc.  (And if you think doing this manually has any value, e.g. trying to get new versions of the apps in your image, you would be wrong.)

image

So now I have a VM that is guaranteed to fail.  So let’s look at what I’ve added to the task sequence to fix this:

image

That step is placed right before the “Execute Sysprep” step (so if you are doing a sysprep-only task sequence execution, you would want to add it to the “Sysprep Only” group too).  The full command line:

powershell.exe -executionpolicy bypass -file %ScriptRoot%\RemoveUserApps.ps1

Resuming the task sequence shows the step running:

image

Then sysprep runs:

image

And if that succeeds, the machine will reboot to Windows PE and capture the image.

image

So yeah, success!

The script itself is attached to a zip file at the bottom of this blog.  While it gets the job done, it’s not perfect:

  • It tries to remove framework packages (basically, dependencies) and fails.  No big deal, as sysprep doesn’t really care about these.  Ideally the script would filter these out, but it’s not worth the effort.
  • It can’t count.  It tries to count up the number of apps that it removes, but doesn’t take into account failures (e.g. those same framework packages).  Error handling wasn’t worth the effort.

Feel free to try it out yourself.

RemoveUserApps.zip

NEW: Upgrade to Windows 10 1803 without suspending BitLocker

$
0
0

One of the new features mentioned in the What’s new in Windows 10 1803 documentation is a new ability to perform a feature update without suspending BitLocker.  This is what it says:

New command-line switches are also available to control BitLocker:

Setup.exe /BitLocker AlwaysSuspend 
    – Always suspend bitlocker during upgrade.
Setup.exe /BitLocker TryKeepActive 
    – Enable upgrade without suspending bitlocker but if upgrade, does not work then suspend bitlocker and complete the upgrade.
Setup.exe /BitLocker ForceKeepActive 
    – Enable upgrade without suspending bitlocker, but if upgrade does not work, fail the upgrade.

For more information, see Windows Setup Command-Line Options

And if you look at the Windows Setup Command-Line Options page, it confirms the same thing: there are new command line options that affect how BitLocker is handled during feature updates.  Let’s dig a little deeper though to understand the requirements.  In order to successfully use this feature, the device needs to meet the following requirements:

  • It needs to be running Windows 10 1709 or higher, and needs to upgrade to Windows 10 1803 or higher.  (So this is a “going forward” change, not one that goes back into the Windows 10 stone ages.)
  • The Windows device needs to be using Secure Boot and have a TPM.
  • BitLocker needs to be using a TPM protector only (yet another good reason to not have a PIN).
  • The user profile folder can’t be on a separate volume that is also BitLocker protected.  (If you are doing something like this, we really need to talk.)

You could add a command line option (through a ConfigMgr task sequence variable, MDT script edit, SetupConfig.ini file, etc.) to explicitly make your choice, but if you don’t, what’s the default?  The easiest way to find out (since the documentation doesn’t say) is to try it.  First, let’s look at a device that was updated from Windows Update.  The SETUPACT.LOG clearly shows the default behavior:

2018-05-01 19:36:53, Info                  SP     Client requested to suspend BitLocker unconditionally

Now, a second device updated using media (SETUP.EXE /AUTO UPGRADE):

2018-05-01 19:22:27, Info                  SP     Client requested to suspend BitLocker unconditionally

OK, also off, so both mechanisms (servicing and media) are acting like /BitLocker AlwaysSuspend was specified, so that’s the default (at this point at least, that could change in the future).  Interestingly, if you have a device that is enrolled in Insider Preview, you might see a different default as new Insider builds are installed.  I can see that TryKeepActive is the default for my Insider laptop:

2018-04-19 15:28:08, Info                  MOUPG  SetupManager: No BitLocker command line option specified, will try to keep active but suspend on errors, because this is a WU scenario



2018-04-19 15:28:08, Info                  MOUPG  ImageDeploy: Initializing BitLocker Mode:        [Keep Active (Best-Effort)]

2018-04-19 15:28:15, Info                  SP     CNewSystem::PreInitialize: Velocity feature state for BitLocker auto-unlock is enabled

2018-04-19 15:28:15, Info                  SP     Client requested to keep BitLocker active on a best-effort basis, and the device supports it. Will try to keep BitLocker on, and fall back if needed.

(That’s the cool thing about Insider Preview, you can be trying out new features that are behind the scenes without really even being aware of them.)

Alright, so we’ve established that the default is presently /BitLocker AlwaysSuspend for both servicing (WU, WUfB, WSUS, ConfigMgr Windows 10 Servicing) and media-based (SETUP.EXE, ConfigMgr task sequence, MDT task sequence) upgrades, while the default is /BitLocker TryKeepActive with Insider Preview devices (well, at least for mine).  So how do we change it to TryKeepAlive?  It depends:

Of course only make those edits/changes if you are upgrading exclusively to Windows 10 1803, since earlier versions of SETUP will have no idea what to do with that command line switch and will most definitely fail.  (But hey, we’re all upgrading to 1803 now, right?)

Troubleshooting Improvements in Windows Autopilot

$
0
0

I wrote a couple of blogs (the basics and the more advanced scenarios) about troubleshooting Windows Autopilot late last year, which focused on the capabilities that existed at that point in time.  But there have been some enhancements since then:

  • Registry entries, so you can see the Autopilot-related activity after the fact.  This was introduced in Windows 10 1709.
  • Event log entries, to show the Autopilot-related activity in a more friendly form.  This was introduced in Windows 10 1803.

Of course you can continue doing ETW traces if you like, but the registry and event log entries are nice because they don’t require reproducing the scenario with a trace running.  Let’s look at each of those in more detail.

Registry information

There are some key pieces of information stored in the registry on Windows 10 1709 and above.  These can be found at HKLM\SOFTWARE\Microsoft\Provisioning\Diagnostics\AutoPilot.  Here are the properties you will see:

  • AadTenantId – The GUID of the Azure AD tenant the user signed into.  This should match the tenant that the device was registered with, since you’ll get an error if they don’t match.
  • CloudAssignedTenantDomain – The Azure AD tenant the device has been registered with, e.g. “contosomn.onmicrosoft.com.”  If the device isn’t registered with Autopilot, this value will be blank.
  • CloudAssignedTenantId – The GUID of the Azure AD tenant the device has been registered with (the GUID corresponds to the tenant domain from the CloudAssignedTenantDomain registry value).  If the device isn’t registered with Autopilot, this value will be blank.
  • IsAutoPilotDisabled – If set to 1, this indicates that the device doesn’t believe it is registered with Autopilot (but this could happen if there were network connectivity issues, timeouts downloading the Autopilot profile settings, etc.).  This is a good place to start troubleshooting, since the value must be 0 (not disabled) for the standard Autopilot behaviors to happen.
  • TenantMatched – This will be set to 1 if the tenant ID of the user matches the tenant ID that the device was registered with.  (If this would be false, the user would be shown an error and forced to start over.)
  • CloudAssignedOobeConfig – this is a bitmap that shows which Autopilot settings were configured.  From the previous level 300/400 blog, bit values include:
    • SkipCortanaOptIn = 1,
      OobeUserNotLocalAdmin = 2,
      SkipExpressSettings = 4,
      SkipOemRegistration = 8,
      SkipEula = 0x10

So first, let’s look at a device that wasn’t deployed using Autopilot, running Windows 10 1709 or above.  Here’s what you should expect to see:

image

Notice the numbered subkeys?  Those correspond to different pages in OOBE.  Each of those keys will contain a value named “ConfigName” that says what Autopilot setting it is tied to (e.g. page 0 is the “personal or work” question, configured by a ZTP_CONFIG_AAD_JOIN_ONLY flag that really means “you don’t need to ask”) and a second “Enabled” value that indicates whether the page was displayed (value 1) or skipped (value 0).  (You might notice that the subkeys are different in Windows 10 1709 and 1803, as there are new things in 1803 that need to be skipped.)

Now, let’s look at a device that did use Autopilot (in this case on a Windows 10 1803 device, so there are some more subkeys and a few other properties that we’ll skip over for now):

image

So I can see that my device was enrolled, what tenant it was enrolled with, that the user signed in with the right tenant, and that the bitmap config is 28, which translates to

SkipExpressSettings (4) + SkipOemRegistration (8) + SkipEula (16) = 28

And if we click into each of the subkeys, we can see all of the different OOBE pages that were skipped.

Event Log

Windows 10 1803 takes diagnostics to the next level with event log entries.  To find the events, open Event Viewer and navigate to “Application and Services Logs –> Microsoft –> Windows –> Provisioning-Diagnostics-Provider –> AutoPilot”.  If the device isn’t registered, you will only see two events (basically indicating that the device is not registered).  If the device is registered and deployed with Autopilot, you’ll see a lot more:

image

Let’s look at some of the event IDs, in the order that you might typically see them:

  • Event 100, warning.  “AutoPilot policy [name] not found.”  This is typically a temporary problem, while the device is waiting for an Autopilot profile to be downloaded.
  • Event 160, info.  “AutoPilotRetrieveSettings beginning acquisition.”  This shows that Autopilot is getting ready to download the needed Autopilot profile settings.
  • Event 164, info.  “AutoPilotManager determined Internet is available to attempt policy download.”  Pretty obvious.
  • Event 161, info.  “AutoPilotManager retrieve settings succeeded.”  A good sign, we were able to download the settings (and you can see how long it took).
  • Event 153, info.  “AutoPilotManager reported the state changed from [original state] to [new state].”  Typically this should say “ProfileState_Unknown” to “ProfileState_Available” to show that a profile was available for the device and downloaded, so the device is ready to be deployed using Autopilot.
  • Event 171, error.  “AutoPilotManager failed to set TPM identity confirmed.  HRESULT=[error code].”  For now, you can ignore this error as it’s related to a future scenario.  
  • Event 172, error.  “AutoPilotManager failed to set AutoPilot profile as available.  HRESULT=[error code].”  Ignore this one too, it’s related to the previous one.
  • Event 163, info.  “AutoPilotManager determined download is not required and the device is already provisioned.  Clean or reset the device to change this.”  This is just telling you that there is now a profile on the device, it’s not going to go away on its own and there won’t be any attempts to download it again.  So you can ignore this one.
  • Event 111, info.  “AutoPilotRetrieveSettings succeeded.”  This means that the bitmap settings stored in the Autopilot profile have been retrieved successfully, so Autopilot now knows how to tell OOBE to behave.
  • Event 109, info.  “AutoPilotGetOobeSettingsOverride succeeded:  OOBE setting [setting name]; state = [state].”  This shows Autopilot retrieving and processing various OOBE settings.
  • Event 101, info.  “AutoPilotGetPolicyDwordByName succeeded: policy name = [setting name]; policy value [value].”  This is very similar to the previous one, just for a slightly different type of setting, an integer.
  • Event 103, info.  “AutoPilotGetPolicyStringByName succeeded: policy name = [name]; value = [value].”  Also similar to events 101 and 109, but for string values (e.g. the tenant name).

So definitely check those out, they are very useful to follow the process, to see any errors that might have occurred (e.g. timeouts), and to confirm that the device is configured the way you expect it to be.

More to come

If you remember the errors shown in the previous blogs, it’s quite possible that you’ll see a screen that says “Something went wrong” with a typical error code, e.g. 80180018.  While we haven’t yet fixed those, we do understand that something more descriptive would be more helpful.  So we’re working on those, especially for common enrollment and join issues.  Stay tuned for future feature updates.

Yet another way to clean up in-box apps

$
0
0

Starting with Windows 10 version 1703, you can now remove provisioned in-box apps like Xbox using the MDM platform capabilities built into Windows.  (If you think you need to use this to remove Candy Crush, Pandora, etc., stop and read this blog before continuing.)  See https://docs.microsoft.com/en-us/windows/client-management/mdm/enterprisemodernappmanagement-csp for the description of the “RemovePackage” method.  While ideally this would be available via Intune, it isn’t at this point (and no, you can’t use an OMA-URI for it either because it uses an Exec method, which isn’t presently support by OMA-URI custom policies).  But fortunately, it is supported by the Set Up School PCs app (which has a hard-coded list of apps that get removed when you create a provisioning package with this tool) and by Windows Configuration Designer (at least in the version from the ADK for Windows 10 1803).

So let’s set up a sample provisioning package using Windows Configuration Designer.  To do this, create a new provisioning package in “advanced” mode, then navigate to “UniversalAppUninstall –> RemoveProvisionedApp.”  Once there, you can specify the apps you want to remove using the “package family name.”  I specified two that I wanted to remove: the Xbox app and the “Get Office” app‘

image

So how do you come up with those PackageFamilyName values?  That’s where PowerShell comes in handy.  For some strange reason, the obvious mechanism of using “Get-AppxProvisionedPackage –online” doesn’t return the PackageFamilyName, but the “Get-AppxPackage” cmdlet does.  So use that to get a list.  Here’s an example for the Xbox app:

image

Copy and paste that value into Windows Configuration Designer, click Add, and then you can generate your provisioning package.  To install it, you can included it in your image (DISM can be used from Windows PE to stage the package for Windows to process automatically on first boot) or you can install it directly using “Install-ProvisioningPackage C:\Project_1.ppkg”.  But if you try it, you’ll find that it does absolutely nothing – because your package doesn’t have any details in it.

Alright, why not?  Simple: there is a bug in Windows Configuration Designer, it doesn’t save the values that were entered in the UI for that setting.  So on to plan B:  Let’s see what the Set Up School PCs app does.  Install it from the Microsoft Store, launch it, and specify all the defaults.  Eventually, you’ll be asked to insert a USB key; it will create a provisioning package on that USB key.  Take that provisioning package (the name of which will start with SetUpSchoolPCs) and copy it to your computer.  Rename it from “.ppkg” to “.wim”  Then mount it using DISM.  From the mounted folder, open the “Multivariant\0\customizations.xml” file with Notepad or your favorited editor.  You should see a section called UniversalAppUninstall that is populated with a list of apps to remove (even though the Set Up School PCs app never asked – it always removes these):


image

Cool, so now how do we get that into our provisioning package without the rest of the Set Up School PCs stuff?  Copy and paste of course.  But first, make a copy of that customizations.xml file, because it’s easier to remove stuff you don’t want.  First, edit it to look something like this:

image

We could just overwrite our own customizations.xml file with this one, but then it would have the same GUID and other details, so instead just copy the “Settings” section into the WCD customizations.xml file (at whatever location you saved it, typically inside the documents folder), overwriting the existing Settings section.  You should then have something that looks the same as the edited SUSPCs file:

image

(Notice that I shortened the list of apps to be removed, back to my original two sample apps.  The SUSPCs list was longer, removing everything that schools want to keep away from students.)  Save the changed file, then open it back up in Windows Configuration Designer:

image

So at least it *reads* the values in, even if it won’t write them.  So *now* you can create a provisioning package that will actually do something, then install it using PowerShell:

image 

And presto, the provisioned apps are removed. But they aren’t removed from any existing user, so while the above PowerShell command works fine, it won’t completely eliminate the apps.  So it’s better to use the “add to the image with DISM” approach.  While you can inject it into your image, it’s better to add it just in time.  Assuming you are using MDT or ConfigMgr, you can add a step to the task sequence that runs in Windows PE after the OS has been applied/installed, that runs a command similar to this:

DISM /Image=C:\ /Add-ProvisioningPackage /PackagePath:Project_1.ppkg

Of course you should be more dynamic about it, specifying the path to the OS (which might not be C:\) and to the provisioning package (which could come from a ConfigMgr package and be in the working directory, e.g. “.\Project_1.ppkg”, or could be on an MDT deployment share and referenced via “%ScriptRoot%\Project_1.ppkg”).  There are other blogs out there that talk about those approaches, so take your pick.


Deploying a kiosk using Windows Autopilot

$
0
0

In today’s Tech Community blog, we talk about a variety of new Autopilot features.  For the Autopilot self-deploying mode, I thought it would be useful to get into more of the specifics of how to deploy a kiosk with Autopilot, where the end result is a device that is configured to automatically log in and run a specific kiosk app (in this case, the new Kiosk Browser app configured to automatically load a specific web page).

Let’s start with some specific requirements before you get too far:

  • The device must have a physical TPM 2.0 chip.  Devices with virtual TPMs (e.g. Hyper-V VMs) or those with TPM 1.2 chips won’t work with self-deploying mode.
  • The device must be running an Insider Preview build of Windows 10, build 17672 or later.  (If you try this with Windows 10 1803, it won’t work very well – it’s only supported with these later builds.)

With that out of the way, let’s get into the specific steps.

Step 1:  Create Autopilot profile

Let’s start off on the Autopilot side.  We first need to create an Autopilot profile for “Self-deploying” mode.  So let’s navigate in the Azure Portal to “Intune –> Device Enrollment –> Windows enrollment –> Deployment Profiles.”  From there, you can create a new profile that specifies “Self-deploying”:

image

Configure the appropriate settings on that profile:

image

Notice that you can specify a “Language (Region)” setting that can automate the initial prompts in OOBE – this only works for wired Ethernet connections though, because the Autopilot settings can’t be downloaded until there is a network connection in place.

Step 2:  Assign Autopilot profile

Intune now uses Azure AD groups to assign Autopilot profiles to devices.  So to use the Autopilot profile that we just created, we need to first create an Azure AD group that can be used for that assignment.  Navigate to “Azure Active Directory –> Groups” and create a new group.  In my case, I created a “Kiosk Devices” group:

image

Now go back to the Autopilot profile that you created before, and click on “Assignments.”  Click the “Select groups” button and find the group that was just created:

image

Click “Select” then “Save.”  Now, any device added to the group will automatically get this Autopilot profile.

Step 3:  Add a device

To do a “Self-deploying” device, we need one that meets the requirements:  It must have a TPM 2.0 chip (and it must be a physical device, a Hyper-V VM won’t work), and should be running a current Windows 10 Insider build (e.g. 17686).  You can gather the hardware hash from it using the Get-WindowsAutoPilotInfo script, then import it via the "Intune –> Device enrollment –> Windows enrollment –> Devices” node.

After that import completes (it will take a few minutes), not only will there be an entry in the list of Autopilot devices, but there will also be a new Azure AD object created for the device.  If you go to “Azure Active Directory –> Devices” you’ll see the device in the list.  The device will be named using the serial number of the device, and will be shown as disabled.  When the device is actually deployed, you’ll see the object renamed to reflect the computer name (instead of the serial number) and it will then be enabled.

Now let’s add the device to the Azure AD group that was created earlier.  Find the group (“Azure Active Directory –> Groups”), click to see its details, and then click “Members.”  Click “Add members” and select the device you imported:

image

Then click “Select” to add it.  After a few minutes, Intune will assign the Autopilot profile to the device; you can confirm that the assignment is complete via the Autopilot devices list (“Intune –> Device enrollment –> Windows enrollment –> Devices”).

Step 4:  Get and deploy the Kiosk Browser app

To have a kiosk that runs a single app, you need a single app.  Fortunately, we now publish a Kiosk Browser app that works nicely, and more importantly it can be easily configured via Intune as well.  But first, we need to get that app.  It’s available in the Microsoft Store for Business, so you need to acquire it from there.  (If you haven’t yet integrated the Microsoft Store for Business with Intune, see the Intune docs for setting that up.  And make sure you have enabled offline licenses via the “Show offline apps” slider on the Setting page in MSfB.)

Sign into the store via http://businessstore.microsoft.com.  Search for “Kiosk Browser” and make sure you choose the right one.  Specify “Offline” for the license type and then click “Get the app.”  (If you already have the app with an offline license, the button will say “Manage” – that’s fine, it just means you’ve done this step already.  And if you don’t see the “Offline” choice see the previous note about enabling offline licenses.)

Now that the app has been added to your collection, you can go back into Intune and initiate a sync with the Microsoft Store for Business to get it to show up quickly.  Navigate to “Intune –> Mobile apps –> Microsoft Store for Business” and then click the “Sync” button.  That might take a couple of minutes, but after the sync completes, you’ll see the app in the list at “Intune –> Mobile apps –> Apps.”  Select the app to see its details (it should show “Yes” under “Supports device licensing”), then click “Assignments.”  Click “Add group” and change the assignment type to “Required.”  Click “Included groups” and then “Select groups to include” and choose the kiosk device group that you created in Azure AD earlier:

image

Then click “Select.” In the “Licensing Type” drop-down, choose “Device licensing" then click OK:

image

Then click “OK” again to add the group, and “Save” to save the new assignment.

Step 5: Create and deploy the kiosk configuration

Now we need to specify how the kiosk should be configured.  To do that, navigate to “Intune –> Device configuration –> Profiles” and click “Create profile”.  Give it a name (e.g. “Kiosk Configuration”), choose a platform of “Windows 10 and later” and a profile type of “Kiosk (Preview)”.  You will then see the available setting categories:

image

Click the “Kiosk” setting to see the “one” setting.  As you can see, there’s a little more that needs to be done:

image

So click “Add” to create a kiosk configuration.  Give it a name (e.g. “Kiosk Browser”) and choose “Single full-screen app kiosk” from the drop-down, which then shows additional options:

image

If you’ve ever configured a kiosk on Windows 10, you might remember that you need to specify an AUMID for the app, which is a UWP concept that combines the app package family name with an entry point – basically, a gibberish string that you should never have to type.  Fortunately, Intune will let you pick an app from a list instead, which is much easier.  So under the “*Managed Intune app to use for kiosk mode” click the “Select a managed app” link to choose an app:

image

Search for the Kiosk Browser app and then click on it to accept it.  (Notice that I have two:  one is an online license, one is offline.  Either will work here, since we’re just using the app to get the AUMID.  But in the previous step when we acquired and deployed the app, it needs to be an offline app for this scenario to work.)  Then click OK.  Next, select “Autologon” as the user account type.  This will automatically create a local account on the device and configure it to automatically log on and run the specified app.  Click “OK” to create the configuration, and then “OK” again to complete that settings category.

Next, click on the “Kiosk web browser” category to see the available Kiosk Browser settings:

image

At a minimum, fill in the “Default home page URL” setting to point to an appropriate web page.  Depending on that page, you may want to populate other settings (e.g. restrict where you can navigate to from that page).  You can also control the UI in the browser app itself, e.g. show or hide navigation buttons, and configure when the browser should automatically refresh.  Click “OK” to commit these settings, “OK” to commit both categories, and “Create” to create the configuration profile.

Next, click on “Assignments” for that newly-created profile.  Then click “Select groups to include” and select the same kiosk devices group that was created earlier:

image

Then click “Select” to confirm that group selection, and “Save” to save the assignment.

Step 6: Deploy

Reset the device that you used in step #3.  When it starts OOBE, what you see depends on the device.  If it has an internet connection, it may skip the language, locale, and keyboard selection screens (if you configured a language/locale in the Autopilot profile).  If it needs a Wi-fi connection, you’ll have to do that manually.  It will then get to a screen that requires clicking OK to continue:

image

and a second screen for “Activities”:

image

As we mentioned in the TechCommunity blog, these extra clicks are temporary and will not be necessary in later Insider preview releases.

When the Autopilot provisioning process completes, you should see the device automatically log on and run the Kiosk Browser app, which will navigate to the configured web page.

Autopilot profile assignment using Intune

$
0
0

We’ve had questions over the past several months, as customers scale up with Autopilot, about how to assign an Autopilot profile to new devices, as it can get kind of tedious to have to do this manually each time you add a new batch of devices (either by uploading them yourselves, or having an OEM do it for you).  Fortunately, the Intune team has been busy working on a mechanism to do this.

Let’s start with a basic premise:  Instead of doing things to individual devices or users (which is tedious), you instead want to do things to groups.  And as those groups get new members, those new members should be handled automatically.  That’s the mechanism that Intune uses today for lots of things: apps, policies, settings, etc.  You assign those to a group, and members of that group get whatever is assigned to them.  See this article for an example.

Now, if you think about an Autopilot profile, it’s really just a group of settings that control how the device should behave when it is being set up.  So it makes sense to assign an Autopilot profile to a group so that all devices that are members of that group automatically get that profile assigned.

The Simple Case

In the simplest case, you can do this using a group containing static members.  Let’s walk through an example from my Intune tenant.  First, I have an Autopilot profile called “Kiosk” that is configured with the settings I want:

image

And I have an Azure AD group with a number of devices that are members:

image

So, all I need to do is assign the Autopilot profile to that group.  Select the profile, click on Assignments, click “Select groups” and choose the appropriate group (or groups) that the profile should be assigned to:

image

Click “Select” and then “Save” (don’t forget that step).  In the background, the assignment will be processed.  If you watch carefully, you can see each Autopilot-registered device in that group change from “Not assigned” to “Assigning” to “Assigned” without you doing anything.  (Give it a few minutes.)

Where did the Azure AD device come from?

You might think “how can I add a device to an Azure AD group before it’s joined to Azure AD.”  If so, you’re on the right path.  What happens when you add a new device to Autopilot (via Intune, Microsoft Store for Business, or any other path)?  An associated Azure AD object is automatically created.  That object is named using the serial number of the device, and it is not enabled until the device actually completes the Azure AD join process.  When that happens, the device is renamed to have the “real” computer name from the device.

So these pre-created devices enable you to place the devices into Azure AD groups and use them for Intune assignment purposes.

It’s also worth mentioning that there are multiple properties automatically “tagged” onto those pre-created Azure AD objects; the usefulness of those will become apparent later.  For those that are technically inclined, you can you look at these using the Graph Explorer website.  Here’s an example from my tenant:

image

The key part is the “physicalIds” values (a multiple-value property, basically an array of values):

"physicalIds": [
"[ZTDID]:7ab8b9a0-b753-4598-94dc-ec885e6bdc11",
"[OrderID]:123456",
"[USER-GID]:eff992e4-f88f-4a2b-bf6f-3197add5c88a:6825770233125750",
"[GID]:g:6825770233125750",
"[USER-HWID]:eff992e4-f88f-4a2b-bf6f-3197add5c88a:6896134161355432",
"[HWID]:h:6896134161355432"
]

There are three values that you should be aware of:

  • ZTDID.  This is a unique value (a GUID) assigned to all Autopilot-registered devices.  So you can use this value to easily determine which devices are registered.
  • PurchaseOrderID (not set in my sample above).  This value is set by OEMs when processing an order for new devices; when they upload those devices to the Autopilot deployment service, they will set the PurchaseOrderID value to the purchase order number for the order.  That makes it easy to identify all the devices from a particular order.
  • OrderID.  This value is actually more of a “tag.”  When you upload devices to Intune, you can specify an optional “OrderID” column that is used to arbitrarily group devices.  For example, you could set the OrderID value to “Kiosk” and use that to easily tag all kiosk machines.

All three of these values can be used as part of a dynamic membership rule for an Azure AD group, which leads to all sorts of interesting scenarios.

Assign a profile to all Autopilot devices

If you have simple requirements, e.g. all devices will use the same Autopilot profile, this gets even easier:  You can create an Azure AD dynamic group that automatically selects all devices that are registered with Autopilot.

How do you do that?

Here’s the step-by-step:

    1. Navigate to “Azure Active Directory –> Groups” and click “New group”.
    2. Specify “Security” for the group type, and provide an appropriate group name.
    3. Select “Dynamic Device” as the membership type.
    4. Click “Add dynamic query” and then “Advanced rule” and paste in this exact string (yes, including the parenthesis):

(device.devicePhysicalIDs -any _ -contains "[ZTDId]")

  1. Click “Add query” and then “Create.”

After a period of time (think minutes, not seconds), the group will be populated with all the Autopilot clients defined to your Azure AD tenant.  You can then take the next step of assigning an Autopilot profile to that group.

Assign a profile to a purchase order ID

This is the same basic process, but with a different dynamic query:

(device.devicePhysicalIds -any _ -eq "[PurchaseOrderID]:333000")

Put in your own purchase order ID value (instead of the “333000” value in the sample above) and you’re all set.

Assign a profile to an order ID

Again, just a different dynamic query:

(device.devicePhysicalIds -any _ -eq "[OrderID]:123456")

Put in your own order ID value (instead of the “123456” value in the same above) and you’re all set.

Got any other interesting scenarios?  Leave comments with the details.

New Windows Autopilot resources available

$
0
0

It’s been a busy day for new Windows Autopilot resources.  First, we launched a new Windows Autopilot landing page, with high-level details about Windows Autopilot capabilities and feature (with more to be added in the future, stayed tuned).  Visit https://aka.ms/WindowsAutopilot to check it out.

image

Next, we published a (nearly completely) new set of documentation at https://aka.ms/WindowsAutopilotDocs to help you learn more about Windows Autopilot requirements, scenarios and capabilities, administration, troubleshooting, and more.

image

If you have feedback on the docs, click the “Feedback” link at the top of the page to let us know.  Or, if you are particularly adventurous, you can edit the doc yourself by clicking the “Edit” link, then submit your proposed changes to our documentation team – if they agree with your changes, they’ll approve them for publishing.  (As an added bonus, your small picture can appear as a contributor to the article.)

A recap from Microsoft Ignite 2018

$
0
0

Another Ignite conference has been completed, and I’m on my way back home to sleep for as long as possible.  For those that weren’t able to attend, or for those that did attend but weren’t watching the video wall showing 12 sessions simultaneously, you can catch up via the session recordings that are available through http://myignite.microsoft.com.  Here are a few that I recommend (click the link to get to the video):

There are plenty of other interesting sessions once you finish these 11 hours, but you can discover those on your own…

Speeding up Windows Autopilot for existing devices

$
0
0

At Ignite 2018, we announced Windows Autopilot for existing devices, a new feature designed to migrate devices from Windows 7 (or any other version of Windows, i.e. 8.1 or 10), Active Directory-joined and ConfigMgr-managed, to Windows 10, Azure Active Directory-joined and Intune-managed (with co-management with ConfigMgr if you so desire) leveraging the Windows Autopilot user-driven deployment process to drive the Windows 10 configuration process.

Rob York published a blog that describes the implementation steps, and we’ve also published “official” documentation that walks through it.  If you look at those solutions, here are the high-level steps that they go through:

  1. Boot to Windows PE (no data migration steps, we assume OneDrive for Business already has the data in the cloud).
  2. Format and partition the drive (so this is clearly a wipe-and-load process, not an in-place upgrade – all data, apps, settings, etc. are cleaned from the drive).
  3. Apply the new Windows 10 OS image.
  4. Inject drivers into the applied Windows 10 installation.
  5. Copies an Autopilot configuration file into the proper location in the Windows folder structure (this enables an Autopilot user-driven experience without harvesting and uploading the hardware hash in advance).
  6. Boot into Windows 10.
  7. Install the ConfigMgr client.
  8. Sysprep the Windows 10 OS.
  9. Reboot into Windows 10 OOBE.

This takes quite a while – about 20 minutes to get into Windows 10 the first time, then another 20 minutes to generalize (sysprep) and re-specialize the device.  And that’s before the time it takes for the Autopilot configuration (Azure AD join, Intune enrollment, pushing policies and apps, etc.).

So how can we make that faster?  Simple: Only boot into Windows 10 once, and don’t sysprep it.  (The OS image being applied initially, straight from the Windows 10 media, has already been sysprepped and captured.  What’s the downside?  Well, you can’t customize the Windows 10 OS, but I would argue you don’t really want to do that anyway; the goal is to treat these existing devices just like new devices, which would probably be configured via Intune exclusively, or Intune + ConfigMgr in a co-management configuration.

So let’s look at what that task sequence can look like:

Existing fast TS

Apart from the removed steps from above (6, 7, 8), there are two other changes:

  1. A new step to remove the unattend.xml that the “Apply Operating System” step automatically creates (this gets in the way of Autopilot).
  2. A PowerShell script (“Copy adjusted JSON”) to copy an edited AutopilotConfigurationFile.json into the right location (more on that later).

The net change: 20 minutes or so removed from the process.  You can find an exported version of my task sequence attached to this blog.

Now here’s a little more detail on that “Copy adjusted JSON” task sequence step.  The official docs have you create an AutopilotConfigurationFile.json, with a step that copies the file without any changes to the correct location.  In my PowerShell version of that step, I make one edit before writing the file to the correct location, inserting the existing computer name so that the “new” Windows 10 OS ends up with the exact same name as the “old” Windows 7 installation.  Here’s the script in its entirety:

# Read the current config
$config = Get-Content .\AutoPilotConfigurationFile.json | ConvertFrom-Json

 

# Get the computer name
$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$computerName = $tsenv.Value("_SMSTSMachineName")

 

# Add the computer name
$config | Add-Member "CloudAssignedDeviceName" $computerName

 

# Write the updated file
$targetDrive = $tsenv.Value("OSDTargetSystemDrive")
$null = MkDir "$targetDrive\Windows\Provisioning\Autopilot" -Force
$destConfig = "$targetDrive\Windows\Provisioning\Autopilot\AutoPilotConfigurationFile.json"
$config | ConvertTo-JSON | Set-Content -Path $destConfig -Force

To use the script, save it as AdjustJSON.ps1 and put it in the same folder as the AutopilotConfigurationFile.json that you created following the official documentation.  (And make sure you have PowerShell and .NET included in your Windows PE boot images.)

Try it out, see how it works for you.

 

Attachment:  AutopilotExistingDevices_Fast

Viewing all 67 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>