Category Archives: Powershell

One challange I hear from customers and other IT Pros working with VPP (Volume purchase program) applications from Apple in Intune is that it if you have multiple VPP accounts and need to manage the application deployment for those in Intune there’s no way of seeing which app is linked to a specific VPP account from the Client App -> App overview pane without clicking on the specific app and in the Overview see which VPP account this application was bought with.

Since there’s no column in the Client app -> App overview for showing the VPP account it can be tedious if one application has been bought by several accounts but you need to deploy the app from a specific VPP account or if you just want to have an easy overview.

To solve this I came up with the Idea of using the Owner column and to populate the VPP account information there so we can see it from the App overview pane. And Instead of manually inputting this information for all the VPP apps I turned to our beloved friend Powershell to help us out. There are several levels of automation that can be done but in this post I’m just going to focus on one of the simplest way to get started in my opinion.

The Intune Powershell SDK is an easy way of doing administrative tasks with the help of all the cmdlets that the SDK includes. And if you don’t want to use the SDK and still do the same things that’s also possible since the SDK uses the power of Graph API and invoke-restmethod so you can create your own functions and cmdlets if you feel the need for that but to keep it simple I will not cover that in this post but let me know if that’s something that interest you for a future post.

The script and execution

The first thing thats going to happen is that we need to import the module and then we call the Connect-MSGraph cmdlet that will make prompt for a logon to your tenant. From there we will get all the VPP apps that’s been synced with Intune and store that in a variable.

Once we have all the apps the script will go through all the apps one by one and check if the Owner property of the app object is either Null or empty and if it is we will then update the Owner property with the same information the vppTokenAppleIdproperty currently have.

When working with a client the other day an Interesting situation came up where they had already used Azure AD for a while and now were ready to start using Intune for managing their Windows 10 PC’s. Prior to that they haven’t had any device management like ConfigMgr or Intune before. They also didn’t have any on-prem Active Directory and were only using cloud services like Azure AD and Office 365.

The question that came up was:

How do we enroll existing Windows 10 machines in Azure AD in to Intune and how can we do that with the minimum amount of effort from the end-user?

One of the ways to do it is by enabling the Enable automatic MDM enrollment using default Azure AD credentials policy but the client didn’t want their end-users or admins manually going in and enable that policy on each machine. So the discussion continued on how could me make it easier for the end user to do the things needed to enroll their device. In this post I will cover both the manual of doing it by enabling the policy but this is mainly to give it some context and from their I will show you how it can be done with the help of a provisioning package.

Once you have the provisioning package in place it’s just a matter of delivering it to the end-user in the most simple way possible and let the end-user run the provisioning package.

Enable automatic MDM enrollment using default Azure AD credentials

On all Windows 10 1703 and newer version of Windows there’s a local group policy that can be set to enroll in to MDM using logged on Azure credentials, this comes in handy in a 1 to 1 scenario where the end-user has their dedicated devices. If you have on-prem AD you can create a GPO for this policy but in this example we don’t have an on-prem AD.

And a schedule task gets created by the name of “Schedule created by enrollment client for automatically enrolling in MDM from AAD” which can be found in the task scheduler under

Microsoft -> Windows -> EnterpriseMgmt

Logs and Monitoring

Once the everything is in place you can monitor the process in Event Viewer

From my own testing and experience you will see the following Error message “Auto MDM Enroll Failed (Unknown Win32 Error code 0x8018002b)” for a couple of hours but that’s totally normal and nothing to worry about.

In this specific example it took about 5 hours before it succeeded to do the MDM join and during this time a user was logged on to the machine. If the machine has no user logged on to it or its put to sleep or turned off the MDM join won’t happen.

Windows 10 provisioning package and Windows Configuration Designer

As mentioned earlier in this post if you have on-prem AD you can create a GPO for this policy an roll out it that way. But if you have no on-prem infrastructure at all to we have to find a easy way for the end-user so we can MDM join them without having to manually go in to local policy and enable the policy.

Microsoft documentation on Provisioning package and Windows Configuration Designer can be found here:

In Windows Configuration Designer you are able to something called ADMXIngestion where you can inject ADMX files and configure their settings however I haven’t been able to get that to work when it comes to the MDM policy and its ADMX file. I’m not exactly sure why and while I’m trying to solve that I will instead focus this post on how to get around it and create the same settings as the policy does but with a powershell script instead.

Once you installed Windows Configuration Designer from either the Windows ADK or Microsoft Store it’s time to create the provisioning package we are about to use but to make this work.

We also need a powershell script and a .bat file that calls the powershell script within the provisioning package because there are some challenges when it comes to running powershell scripts directly.

The scripts

In this example we will be using MDMPS.ps1 as our powershell script and MDM.bat

With powershell we create a registry key and a Schedule task which is the same schedule task that runs if one manually enables the MDM join policy on the local computer.

Click on “Browse” and find the .PS1 script file and click on “Add” repeat this for the .Bat file as well.

You should now see the 2 added files under CommandFiles. In this example the MDMPS is the powershell script and MDM is the .Bat script.

Next thing is to click on “CommandLine” and add write “cmd.exe /c MDM.bat” this will tell the provisioning pack to run the .bat file and the .bat file will run the powershell script.

Now we just need to export the provisioning pack and to do so you click on “Export -> Provisioning package” in the top left corner

Give the provisioning package a name and click on “Next”

You can encrypt the package or sign it with a certificate if you want, but since there’s no unique/sensitive or secret information in this specific package you don’t need to do this. Click “Next”

Choose the path where you want to save your provisioning package to and click on “Next”

Click “Build“

On the last page click on “Finish”

Go the file location where you save the file and grab your newly created provisioning package

Applying provisioning package

When it comes to distribution there’s not much we can do without any prior management or on-prem AD so with this one solution is to just email the package to the end-users and just write a small guide on how they apply it.

There’s a few different ways of applying a provisioning package but in this example we will cover one way.

The file needs to be present on a Windows 10 1703 or later PC where the end user is logged on with their Azure AD credentials.

Double click on the provisioning package

If UAC is turned on and gives you a popup, click “Yes”

a provisioning package warning will appear if its not signed, Click on “Yes, add it”

And that’s it.

The powershell script will now create the schedule task and create the registry key needed to do the MDM Join. A few hours later the machine will be MDM Joined in the same way if you enabled the policy. For logs for the MDM join see the section Logs and Monitoring in this blog post.

If you want to make sure the provisioning package has been applied you can go to Windows start menu -> Settings -> Account -> Access Work or School -> Add or Remove provisioning package

For those who want to administrate Intune with the help of powershell there’s been a good source of sample scripts over at https://github.com/microsoftgraph/powershell-intune-samples for quite some time now. If you want to interact with Intune, Azure, O365 and more you need to use Microsofts Graph API. To get started with Intune and Graph API I recommend you take a look at Niall Brady’s post on how to get started

During Microsoft Ignite 2018 in Orlando there was a session about a Powershell SDK for Intune which was very intressting because it removes some of the barriers for people who are used to Powershell but not might have the time to dive in to Graph API specifially. The SDK contains cmdlets that communicates through Graph API behind the scenes but you as the adminstrator doesnt have to think about doing webrequest to the API and so on.

You are now connected and are able to use all the cmdlets against your tenant.

For example

Get-DeviceAppManagement_MobileApps

Will get all applications under MobileApps (Client Apps is the new name in the Intune console)

To list all available cmdlets in the Powershell module just do the following in powershell. As of this post there’s 1311 cmdlets which is pretty impressive I have to say for something
thats just a preview.

Last night for us Europeans there was another ConfigMgr Technical Preview release and this time its version 1710. There are many new great features indroduced to this Technical Preview and the full overview you can find over at Microsoft.

The Wizard

One of the big updates here is the wizard and the ability to get realtime output to show up in the wizard during execution of the script.

When executing the script you will see a green statusbar that indicates that somethings i happening and under that you know have box that will populate with data onces the client have runned the script and reported back which just takes a few seconds.

(Side note, The script I’m running below is just a Ping to localhost on each client)

One of the options you have is the “Script details” found in the botton left corner and here you will se information like “Script name, Script Version, Last modified Time, Collection ID”

In the middle you have “Summary” which is the default one you will see and from here you can change how you want to view the data.

The data you can view is

Script output

Script Exit code

and you can view them as

Bar Chart

Pie Chart

Data table

You can also view this information on scripts you ran histroically if you go to Monitoring -> Script Status and right-click and than click on Show status (You will also able to preview the some information in the lower part of the console)

After clicking on Show Status you will get prompted by this windows containing all the info we saw in the Wizard when executing the script and can sort the data in the same way.

Parameters

The next thing i want to showcase is the Parameter functionallity which gives us the ability to specify a parameter when executing the script towards a collection. Here we are creating a new script which is called “Ping Parameter”

and in this script we will add a parameter and then do a ping with a variable based on that parameter.

Once clicking “Next” we get option to Edit the Parameter

From here we can change a few options like Data Type, required true or false etc. Also able to add a Description that will show up later when executing the script.

Once configured click next and then you have to approve the script as always. Next step is to run the script and when we do that we get the following option now to enter a parameter. In this case we need to enter the computer name we want to ping with the ping script we just created.

The description box shows the information we wrote earlier telling the user who executes the script some information about the parameter and what they need to enter.

We run the script and gets prompted with information as expected

but if we check under “Script Details” we find additional information on the parameter we entered

These are really cool additions to this great feature and I’m really happy that the ConfigMgr team just keep on working on it and add functionallity. Hopefully we can see some of these changes to the pre-release feature in the next ConfigMgr CB build.

One of the new pre-realease features in ConfigMgr 1706 is the Run Script function which makes it possible to run Powershell scripts directly from the ConfigMgr console towards clients. This is a huge benefit to be able to do so because this means as long as the client is active in ConfigMgr console it will execute the script you triggered almost in real time and without going through the process of making sure that WinRM is active on the client and configuring firewall and all the other things that can be an issue when you deal with clients on different subnets, physical locations, behind different firewalls etc. As long as you have your ConfigMgr infrastructure in place and the clients are active you are all good to go.

What you could do and as I will showcase in this post is to invoke Configuration baseline evaluation on demand with the Run script function. I have an old blog post on how to to it with Powershell remotely ( https://timmyit.com/2016/07/26/sccm-and-powershell-trigger-baseline-evaluation-on-client/ ) but that means you have to have everything in place to remote access clients with Powershell which isn’t always the case in a lot of environments for many reasons.

Baseline Evaluation with Run script feature

Here’s the Powershell script we want to use to evaluate all of the baselines deployed to the machines in a device collection. If you just want to evaluate a specific one you need to modify the script.

Note,

When testing this script as a Run script I wasn’t able to run the original Powershell script as a function, it returned Exit code 0 but didn’t execute the evaluation method on the client for some reason through ConfigMgr but it did work when I ran it manually on the client. I’m currently troubleshooting that and will probably file a bug report when I have more info and do a separate blog post on that later. But in the meantime we will just have to skip function part. And just to emphasis this is still a prerelease feature.

This blog post is the first in a series of 2 where i will showcase how to export iprange and subnet boundaries and then how to import them with the help of a powershell script. I’m a big proponent for automating task to increase productivity and I believe in the mindset of always trying to improve what ever you are doing, regardless if that’s improving your workflow or learning something new to improve yourself. Invest time now to save time later but lets get back to the topic of this post and that’s about exporting boundaries from SCCM.

What do we want to achieve?

For example If you are in the process of setting up a new ConfigMgr environment and there’s an existing ConfigMgr environment that’s getting decommissioned but you aren’t performing a site migration and there’s still information like boundaries that
will be reused then here’s a script that will help you export IPRange and Subnet boundaries to .csv so you later can import them in the new environment because there’s no built in function in ConfigMgr to do that at the moment.

In the picture below we have our boundaries we want to export in to a file (in this case a .csv) and then later be able to import them back in to ConfigMgr.