Because of the popularity of my first blog post Deep dive Microsoft Intune Management Extension – PowerShell Scripts, I’ve decided to write a second post regarding Intune Management Extension to further explain some architecture behind this feature and upcoming question from the community. A deeper understanding helps to successful troubleshoot the feature.
Table of content for easy navigation
- Details of the MSI deployment of the Intune Management Extension agent?
- Be aware of the log files regarding sensitive data!
- Getting content of scripts once they are uploaded to Intune?
- What about return codes (exit codes) of PowerShell scripts?
- Where can I find a helpful PowerShell script template to start with?
- Script execution retry interval when failed?
- Can we schedule scripts?
- Integrated HealthCheck of Intune Management Extension agent?
- User interaction and timeout
Details of the MSI deployment of the Intune Management Extension agent?
Please read the first article Deep dive Microsoft Intune Management Extension – PowerShell Scripts, to get an understanding of the MSI install job.
The EnterpriseDesktopAppManagement CSP takes care of this task and delivers the MSI to the device and starts the execution. The CSP provides some helpful information in registry for troubleshooting.
In the registry at HKLM\SOFTWARE\Microsoft\EnterpriseDesktopAppManagement\<SID>\<MSI-ProductCode> you can find helpful information for troubleshooting:

Highlighted value names are described in detail here:
CurrentDownloadUrl: URL to the MSI install file.
EnforcementRetryCount: The number of times the download and installation operation will be retried before the installation will be marked as failed.
EnforcementRetryIndex: The current number of retry.
EnforcementRetryInterval: Amount of time, in minutes between retry operations.
EnforcementStartTime: Start time of enforcement.
EnforcementTimeout: Amount of time, in minutes that the installation process can run before the installer considers the installation may have failed and no longer monitors the installation operation.
LastError: Error after last execution.
Status: The Status can have the following values according to the EnterpriseDesktopAppManagement CSP documentation:
Value = Status
10 = Initialized
20 = Download In Progress
25 = Pending Download Retry
30 = Download Failed
40 = Download Completed
48 = Pending User Session
50 = Enforcement In Progress
55= Pending Enforcement Retry
60 = Enforcement Failed
70 = Enforcement Completed
In case of no sidecar agent on the device the status may indicate an error or it is still in progress of downloading. Try to figure out this status. Correlate the status with your device and environment. There may be a proxy issue?
According to the screenshot above the CSP will try it 3 times with a timeout of 10 min and then it will be marked as failed. Is there a retry after x days, I assume yes but I don’t have some documentation for it. As soon as I have more information I will update the article accordingly.
You might think what about the script execution retry interval when failed and how to enforce a retry, see section Script execution retry interval when failed? Also a very comprehensive article about MSI deployment with Intune can be found here: Support Tip: Troubleshooting MSI App deployments in Microsoft Intune
Be aware of the log files regarding sensitive data!
The following script below will create a local user account with a specified static password. It is a working script, but be aware that it should not be used in production! The whole script content will be logged to the IntuneManagementExtension.log file. There you will find the clear text static password as defined in the script. As an example I have copied and marked the particular log file entries below the script to show that. Disk encryption technologies like BitLocker are lowering the risks a bit, but even then this is not a concept to be used in production environments! An attacker can read the log files with standard user permissions and get the sensitive data. Without BitLocker encryption this can be done even offline!
Again: I do NOT recommend transferring sensitive data like passwords via this approach! I know it’s often done. There is a similar approach for on-prem AD which is often used. The GPO preferences for local user management tasks uses a simple xml file with passwords base64 encoded -> this is not secure! Please consider something that was build for that purpose. Admin account management should be done via LAPS or other third party. I know there is no equivalent solution like LAPS for a cloud only environment right now from Microsoft.
# Author: Oliver Kieselbach # Date: 01/03/2018 # Description: Create a local user account. # REMARK: DO NOT USE IN PRODUCTION, Password will not be unique and be visible in clear text in log file! # The script is provided "AS IS" with no warranties. Param([switch]$Is64Bit = $false) Function Restart-As64BitProcess { If ([System.Environment]::Is64BitProcess) { return } $Invocation = $($MyInvocation.PSCommandPath) if ($Invocation -eq $null) { return } $sysNativePath = $psHome.ToLower().Replace("syswow64", "sysnative") Start-Process "$sysNativePath\powershell.exe" -ArgumentList "-ex bypass -file `"$Invocation`" -Is64Bit" -WindowStyle Hidden -Wait } if (!$Is64Bit) { Restart-As64BitProcess } else { Start-Transcript -Path "$env:temp\CreateLocalUser.log" $password = ConvertTo-SecureString "SecretP@ssw0rd!" -AsPlainText -Force New-LocalUser "John" -AccountNeverExpires:$true -FullName "John Doe" -Password $password Stop-Transcript }
To demonstrate the problem with this approach, here is the corresponding log file part after script execution with the complete script and static password in clear text:

Getting content of scripts once they are uploaded to Intune?
The Intune Azure Portal does not provide any UI element to show the uploaded script again. Thanks to the GitHub repository Intune PowerShell Samples we do not script something by our own. We can use a script provided from there called DeviceManagementScripts_Get.ps1. It will get all uploaded scripts, including script content, and details from the Intune API via Microsoft Graph API.
Get it from here:
https://github.com/microsoftgraph/powershell-intune-samples/blob/master/DeviceConfiguration/DeviceManagementScripts_Get.ps1
Save it locally and run it with PowerShell and provide your Intune Administrator credentials when asked for:

UPDATE: see my blog post about Get back your Intune PowerShell Scripts
What about return codes (exit codes) of PowerShell scripts?
At the moment the Intune Management Extension will gather various results, but the Intune Azure portal does not show them in an UI element (if it will change in the future and we have something available, I will update the post accordingly). As for now scripts can be executed through the Intune agent and the Intune UI will show just the execution state success or failure. The status is related to successful agent execution, like no hash mismatch, no script content problem, and no error output… it does not reflect the script exit code.
Scripts like this, I called it “failscript.ps1” are handled as success at the moment:
[Environment]::Exit(-1)
See here the results in Intune Azure Portal:

Perhaps Intune will show us script exit codes in the UI sometime, then we could verify this easily with the failscript from above.
If we use Write-Error cmdlet in our scripts then Intune will pick up the error output. Here an example:
Write-Error -Message "Could not write regsitry value" -Category OperationStopped
This gives us a failed status in the monitoring section of the PowerShell scripts:

Where can I find a helpful PowerShell script template to start with?
I have made a simple script template which:
- Enforces execution in x64 PowerShell (restart of PowerShell as x64 process)
- Generates a log file in C:\Windows\temp when run in system context
or %LocalAppData%\temp when run in user context - Has exit code handling (exit code is even gathered when restarted as x64 process)
- Uses Write-Error to signal Intune a failed execution and makes sure we have reporting reflecting our script execution success (standard error is even gathered when restarted as x64 process)
For ongoing maintenance it is provided via GitHub Gist:
<# | |
Version: 1.1 | |
Author: Oliver Kieselbach | |
Script: IntunePSTemplate.ps1 | |
Description: | |
Intune Management Extension - PowerShell script template with logging, | |
error codes, standard error output handling and x64 PowerShell execution. | |
Release notes: | |
Version 1.0: Original published version. | |
Version 1.1: Added standard error output handling. | |
The script is provided "AS IS" with no warranties. | |
#> | |
$exitCode = 0 | |
if (![System.Environment]::Is64BitProcess) | |
{ | |
# start new PowerShell as x64 bit process, wait for it and gather exit code and standard error output | |
$sysNativePowerShell = "$($PSHOME.ToLower().Replace("syswow64", "sysnative"))\powershell.exe" | |
$pinfo = New-Object System.Diagnostics.ProcessStartInfo | |
$pinfo.FileName = $sysNativePowerShell | |
$pinfo.Arguments = "-ex bypass -file `"$PSCommandPath`"" | |
$pinfo.RedirectStandardError = $true | |
$pinfo.RedirectStandardOutput = $true | |
$pinfo.CreateNoWindow = $true | |
$pinfo.UseShellExecute = $false | |
$p = New-Object System.Diagnostics.Process | |
$p.StartInfo = $pinfo | |
$p.Start() | Out-Null | |
$exitCode = $p.ExitCode | |
$stderr = $p.StandardError.ReadToEnd() | |
if ($stderr) { Write-Error -Message $stderr } | |
} | |
else | |
{ | |
# start logging to TEMP in file "scriptname".log | |
Start-Transcript -Path "$env:TEMP\$($(Split-Path $PSCommandPath -Leaf).ToLower().Replace(".ps1",".log"))" | Out-Null | |
# === variant 1: use try/catch with ErrorAction stop -> use write-error to signal Intune failed execution | |
# example: | |
# try | |
# { | |
# Set-ItemProperty ... -ErrorAction Stop | |
# } | |
# catch | |
# { | |
# Write-Error -Message "Could not write regsitry value" -Category OperationStopped | |
# $exitCode = -1 | |
# } | |
# === variant 2: ErrorVariable and check error variable -> use write-error to signal Intune failed execution | |
# example: | |
# Start-Process ... -ErrorVariable err -ErrorAction SilentlyContinue | |
# if ($err) | |
# { | |
# Write-Error -Message "Could not write regsitry value" -Category OperationStopped | |
# $exitCode = -1 | |
# } | |
Stop-Transcript | Out-Null | |
} | |
exit $exitCode |
Script execution retry interval when failed?
The PowerShell scripts are executed via agent on the target device. If an execution fails, the agent tries to run the script again during next check-in. Current check-in interval is every 60 minutes. This procedure is limited to 3 attempts!
This is tracked in registry at:
HKLM\SOFTWARE\Microsoft\IntuneManagementExtension\Policies\UserGUID\ScriptGUID
The DownloadCount also means execution count and the result is tracked as Success or Failed.

If we change the run as account (user/system), signature check or script content, the DownloadCount will be reset, and the agent will try another 3 attempts to execute the script.
If a script should be enforced to run again, we can simply reset DownloadCount and ErrorCode to 0 and set Result and ResultDetails to nothing (empty string). After this we just restart the Microsoft Intune Management Extension Service (IntuneManagementExtension) and the script will rerun again on this device.
Can we schedule scripts?
No we do not have a run schedule at the moment. For example the agent does not execute the script every x hours. The agent checks every 60 minutes for new policies in the backend – during this no re-run of scripts occurs once a script is successful executed. If scheduling of scripts is needed I suggest to register the script as a scheduled tasks via PS commands. That’s the only way at the moment (as soon as we have something available for scheduling I will update the post accordingly).
Below a script to copy the scheduled script to a certain folder like C:\ProgramData\CustomScripts\myScript.ps1 and then register a scheduled task to run it periodically:
# Author: Oliver Kieselbach # Date: 01/31/2018 # Description: install ps script and register scheduled task # The script is provided "AS IS" with no warranties. # define your PS script here $content = @" Out-File -FilePath "C:\Windows\Temp\test.txt" -Encoding unicode -Force -InputObject "Hello World!" "@ # create custom folder and write PS script $path = $(Join-Path $env:ProgramData CustomScripts) if (!(Test-Path $path)) { New-Item -Path $path -ItemType Directory -Force -Confirm:$false } Out-File -FilePath $(Join-Path $env:ProgramData CustomScripts\myScript.ps1) -Encoding unicode -Force -InputObject $content -Confirm:$false # register script as scheduled task $Time = New-ScheduledTaskTrigger -At 12:00 -Daily $User = "SYSTEM" $Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ex bypass -file `"C:\ProgramData\CustomScripts\myScript.ps1`"" Register-ScheduledTask -TaskName "RunCustomScriptDaily" -Trigger $Time -User $User -Action $Action -Force
Here some documentation regarding PowerShell and scheduled tasks:
https://docs.microsoft.com/en-us/powershell/module/scheduledtasks/register-scheduledtask?view=win10-ps
But you need to think about a strategy how to track all this or how to modify in the future. Once set you may want to have a modification script to change schedules or even delete it from the device again.
Integrated HealthCheck of Intune Management Extension agent?
The Intune Management Extension creates a scheduled task which will run a Health Check once a day.

If familiar with ConfigMgr and the ConfigMgr agent, there we have the same concept. The health check involves 4 files:
ClientHealthEval.exe and ClientHealthEval.exe.config: The binary which runs the health check.
HealthCheck.xml: The xml with all rules to run to perform the health check.
HealthReport.json: The json report with results of the rules defined by the xml.
The tests are defined in the xml file to check the agent registered service, startup type, service status and memory usage.
User interaction and timeout?
When using a scripts with the typical user interaction (like shown as an example in my first article Deep dive Microsoft Intune Management Extension – PowerShell Scripts), be advised that this script is getting executed and showing a dialog which blocks the script from finishing, until the user interacts with the dialog and then let the script finish. This can lead to timeouts and then scripts are getting marked as failed even when successfully ran.
The current default script timeout is 30 minutes for execution which is currently not adjustable.
PowerShell scripts execution without user logon?
Since 22th of October the end users are no longer required to be logged in on the device to execute PowerShell scripts.
If you find something missing or changed feel free to leave a comment. Thanks!
Do i understand it correct that the PS script that is send with Intune, reads the content of the txt file @ the location $content and creates a PS1 script from the content? Very nice idea and blogpost. We could also combine this with Azure File Storage for storing and retreving files.
Yes the script itself is defined in the content variable and then written to disk. I thought it’s nice to demonstrate such an approach. Combination with Azure Blob storage or File storage would certainly be possible. For this simple task it would require more involved services which must be configured upfront, but for different cases certainly useful.
Oliver, fantastic work, thanks!
One addition if someone is trying to get the Intune PowerShell script exit codes and the outputs of the script, these are available in the Microsoft Graph.
If you visit https://graph.microsoft.com/beta/deviceManagement/deviceManagementScripts/ you will get the list of the PowerShell scripts in Intune with their properties.
By selecting the “id” of your script, you can deep dive into execution data.
Under deviceRunStates you get access to all the relevant information:
eg. https://graph.microsoft.com/beta/deviceManagement/deviceManagementScripts/b6759ffb-063c-4f96-8199-bd30d0e41467/deviceRunStates
You get a list of entries like this one:
{
“id”: “–deleted–“,
“runState”: “success”,
“resultMessage”: “\r\n”,
“lastStateUpdateDateTime”: “2018-03-30T21:14:13Z”,
“errorCode”: 0,
“errorDescription”: null
},
It is easy to combine with the Intune DWH in Power BI.
Have fun with it!
Thank you Márton!
And yes this is definitely a way to get to some good reporting. I would love to see this in the native Intune Azure portal but we will see what the future brings us. The Intune service gathers the information quite a while but does not expose them in the UI. I guess for the time being the only way is to build something our own. Very good that you mentioned it here.
This didnt work for me 😦 so I can see that the script is been created and the files are downloading from my blob, however, the task is not been scheduled :S
The only thing I have changed is
$Action = New-ScheduledTaskAction -Execute “C:\ProgramData\CustomScripts\CS_Agent_Deploy.bat”]
The scripts works create when it runs directly on the machine but when I try and deploy it through intune it simply will not create the task…?
Does anyone have any ideas?
Hi Nick,
I verified my sample script again and it’s still working (executed it on 2 AAD/Intune devices successfully). Did you configured my sample script and is this working in your environment? I’m not seeing a failure in your command line. Maybe try to use $Action = New-ScheduledTaskAction -Execute
“cmd.exe” -Argumente “C:\ProgramData\CustomScripts\CS_Agent_Deploy.bat”
best,
Oliver
Not sure if your reply has a typo, but i guess -Argumente should be -Argument.
Also a question, that 10 min script timeout is only for user dialogs, or for every script that is running (I have some issues with Illustrator deployment, that says it failed but work perfect on the machine).
Hi,
Sorry for my delayed response I was in vacation. Yes you are right it should be -Argument (see here: https://docs.microsoft.com/en-us/powershell/module/scheduledtasks/new-scheduledtaskaction?view=win10-ps)
The 10 min. timeout is currently the default for every script.
best,
Oliver
Hi Oliver,
I have some troubles with large files while using the EXE deployment method.
Probably even the download takes 10+ minutes.
Do you have any tips orso for the 10min timeout?
I guess I am not the only one with this question 🙂
Honestly not at the moment. Sure it’s possible to write an wrapper to execute something on the client and return a success result code to Intune but then you would loose proper reporting. It would be possible to report a result code to a azure function or azure storage or log analytics and then build a dashboard to evaluate these results… but imho this is not very ideal. I think MS has to deliver something here in future. If you like to discuss about other options beside Intune maybe drop me an email.
best,
Oliver
I am currenlty checking with a hash check in the beginning of the script. If its not the same, it will download the ZIP and will exit with exit code 1.
Else it will extract the zip, and do all the other commands and clean up tasks.
Right now I can see some green status messages for some machines and adding some more machines to be sure it wasnt luck. I do not like this solution, but right now I think it is the only way.
if you have a variable as part of the script which writes to file it does not write the variable for some reason. Any ideas?
Can you share the code snippet otherwise it would be hard to debug. It should work. Maybe you write to a location where user has no permission?
Hi Olivier,
The Intune Management Extension won’t get installed on multiple test clients of me. The registry values/folders you are talking about aren’t even created. Is there something else I can check or is it possible to install the extension manually?
All the requirements are ok.
– Test device: Windows 10 1803
– EMS E3 license
– Auto Enrollment enabled
– Azure AD Joined
All other policies are applied as expected.
Thank you
Hi,
One question because you didn’t mentioned this. Did you actually assigned a PowerShell script to a user? The agent itself can be installed on-the-fly by Microsoft. So it might be that your machines you are investigating the problem don’t have received a trigger to do the agent install. As soon as a script is assigned the agent will checked and if needed updated or even installed if not available.
best,
Oliver
Hi Oliver
Great article, thank you.
I have a similar issue to InTuneDude above. I have assigned a Powershell script to some test devices in InTune. The InTune Management Extension gets installed, but the scripts don’t execute.
The registry key HKLM\SOFTWARE\Microsoft\IntuneManagementExtension exists, but the subkey ‘Policies’ does not. Also, the subfolder ‘Policies’ does not exist in C:\Program Files (x86)\Microsoft Intune Managment Extension.
Other policies from InTune are applying successfully (autopilot, app installations, device sonfiguration). Any pointers?
Thank you
Nick
Hi Nick,
thanks. First of all are you assigning the PowerShell scripts to users? This is necessary. The policies key is only available as soon as you got the first PowerShell script on your device. Please verify with user assignment.
best,
Oliver
Hi Oliver
The script are assigned to devices – I’ll try assigning to users instead.
Thanks
Hi Oliver,
Great article! It’s a shame that we can’t provide a secure/encrypted object with PowerShell scripts in Intune, for preventing sensitive data from being exposed.
I wrote an article about an alternative solution for creating Local Administrator accounts and storing their passwords using Intune PowerShell scripts, Azure Functions and Azure Key Vault.
I would be pleased if you would take a look at https://www.srdn.io/2018/09/serverless-laps-powered-by-microsoft-intune-azure-functions-and-azure-key-vault/
Looking forward to hear your thoughts!
Hi John,
nice work and I’m glad that you openly communicate the pitfalls of the solution. So everyone gets a clear picture and can rate the pitfalls and the benefits by their own.
Something which comes to my mind is, that a device can be renamed by a user easily with the company portal for example. As soon as this happens it might be difficult to identify the device when you need the local admin password.
I’m curious in the scenarios you are using the local account. We have several thousands of computers migrated now with the modern management approach and Intune etc. and we can life without a local admin account. In the beginnings I thought this is a must have feature, but by now it’s not that important for us anymore. Can you tell me about your scenarios where you are using or depended on a local admin account?
best,
Oliver
We need a local admin account so that service desk users can remote using logmein to do admin tasks without being global administrators of Azure.
I was able to leverage custom Custom OMA-URI Settings in device configuration in Intune to create an account and assign a password however i cant change the password if I need to.
What i tried to do is run a powershell script from intune to delete the account but im getting a “the term remove-localuser is not recognized”. Which is weird because I can run that command locally.
wondering if you can assist?
Hi Adeel,
first of all you don’t need to be global administrator to remote logon, you can add additional administrators to your Win10 AADJ devices by navigating to portal.azure.com > Azure Active Directory > Devices > Device Settings > additional local administrators on Azure AD joined devices > click selected > add your accounts. Global Administrators should be a very low number and service desk should only get the rights to the devices not global admin permissions.
Regarding the localuser PS cmdlets you need to run it from 64-bit process. Try to run “Get-Command Get-LocalUser” from a x86 PowerShell and you will see Get-LocalUser is not recognized as cmdlet. Running from x64 will succeed. To accomplish New-LocalUser execution, try my script example from GitHub https://github.com/okieselbach/Intune/blob/master/ManagementExtension-Samples/IntunePSTemplate.ps1. This will re-launch the process in x64 and the cmdlet should succeed.
best,
Oliver
Using Intune I already have a PS script called Invoke-MSIntuneDriverUpdate.ps1 that we are using to update drivers on the machines. I am wanting to get that script to a schedule task to run monthly. Will your install ps script and reguster scheduled task work for that? We are using only Intune, no SCCM or any other piece of software.
Thanks!
Hi Brent,
I guess it’s the script from my SCConfigMgr colleague Maurice and this script is about 30KB in size. So you could embed this into my demo script but you could also take his script and build a .intunewin package to deploy it. That would be my preferred way of doing it. You could put the driver script into the source folder and another installer script which copies it over to the device and registers the task. The nice thing about this is, you get also uninstall capabilities. So put you installer PS script and Maurice script into a Win32 app package, build the .intunewin and call in the command line powershell -ex bypass -file yourinstaller.ps1 to get it working.
best,
Oliver
When it asks me to specify the setup file it wont let me put the PS Script and Maurice Script at the same time. I can build each out individually as .intunewin but wont let me select both.
You don’t need to specify both scripts during .intunewin creation, put both scripts in the source folder and just specify your newly created installer.ps1 and then when built go into the Intune portal and use the command line: powershell.exe -ex bypass -file installer.ps1.
In your installer.ps1 make sure to copy the Invoke-MSIntuneDriverUpdate.ps1 script somewhere into the file system (e.g. C:\ProgramData\MyDriverScript\Invoke-MSIntuneDriverUpdate.ps1) and register the scheduled task and specify the UpdateDriver script in the scheduled task with the file path on the disk like in the example: C:\ProgramData\MyDriverScript\Invoke-MSIntuneDriverUpdate.ps1… I think you get the idea right?
best,
Oliver
Using $process = Start-Process -PassThru causes the command to return a process object that contains the StandardInput, StandardErrors and StandardOutput properties. Great for catching events that happened in the x64 powershell instance.
Oh yes that’s right -PassThru… during writing I didn’t thought about that. I should really build and test a new version which is then even simpler. 👍
Good advice!
Hey Oliver, I have a PS script to create a Task. I dont want to run it in the user context when creating the task but when i do this i get an access denied message creating the task. Do you have any tips creating a task in the system context (again not running the script as system but creating the actual task)
Thanks!
Hi Andrew,
have you seen the example from me here:
https://oliverkieselbach.com/2018/02/12/part-2-deep-dive-microsoft-intune-management-extension-powershell-scripts/#schedule-scripts
In general it is working to create a schedlued task in system context and use a user as context within the scheduled task.
This example is running also in system context on my device.
$Time = New-ScheduledTaskTrigger -At 12:00 -Once
$User = “desktop-2urhh1q\oliver”
$Action = New-ScheduledTaskAction -Execute “powershell.exe”
Register-ScheduledTask -TaskName “SoftwareScan” -Trigger $Time -User $User -Action $Action
to test things out before running it with Intune use “psexec” from sysinternals (https://live.sysinternals.com/) and run a cmd in system context via ‘psexec -e -s cmd’
then make sure your cmd is running in system context via running “whoami” you should see something like “nt authority\system”, then start the powershell and verify your created PS script if it is running in system context successful.
best,
Oliver
hello Oliver
greate article thanks for it.
I am a beginer and need som guide. I created a PS script to copy some protected files. but this script fuailer becuase it is not runing as admin.
good to know all our users does not have a local admin rights.
is there any way to run the script as admin via Intune?
best regards
Sinan
Hey Sinan,
you can run a script easily with high permissions in SYSTEM context by setting this:
Run this script using the logged on credentials: No
The problem which can occur is, that user environment variables like %userprofile% will not resolve to the user path as you are running in SYSTEM context. So you need to make sure your path variables are still correct and then you are able to to whatever you want in system context.
best,
Oliver
Hey Oliver,
A couple of questions:
Does a system context script only run once? Asking because I have a script to set the time zone but the devices are reverting back for some reason.
Also if I run a script under the user context, the user MUST be able to run that script, correct? For example a standard user wouldn’t be able to run the below (mostly the service restart).
Set-TimeZone -Name ‘Eastern Standard Time’
Start-Service W32Time
Restart-Service W32Time
Also here’s a fun one for you with PowerShell (have a case opened with MS so feel free to ignore)
We have a complex issue with our Windows Autopilot Process. As part of our network security infrastructure, we require our Corporate owned devices to only access our corporate WiFi via certificates. Through AutoPilot, we push down a ROOT, CA, and the device obtains a SCEP certificate from our NDES server. In addition to these settings we block access to our Corporate Guest Wifi via a PowerShell script (netsh wlan add filter permission=block ssid=Wifi-Guest-Network networktype=infrastructure).
Herein lies the issue, during the Windows AutoPilot process, we connect to our guest network because these devices come from the factory but as the configuration gets pushed down, the Guest Wifi is block via the PS script and the device will stop configuring. How do we make sure the PowerShell script that blocks Guest WiFi runs as the absolute last configuration so the device gets properly configured?
Hi Shant,
delayed as this is my first day back from vacation. Yes the script runs only once. If you like to run it multiple times I suggest to use a scheduled task register a scheduled task and run your code periodically.
User context script can only do actions which are allowed in user context, so you are right you can’t restart the service. You can play around with dependencies to accomplish a script restarting the W32time service and as dependency setting the timezone. that way you could run it in different contexts.
Your Wi-Fi issue sounds solvable to me :-). Why not using a scheduled task here as well. Build a PowerShell script which registers scheduled task which as a custom trigger. This trigger is the trick. search for something which is fired after all is done in your deployment chain. So for example if you use Enrollment Status Page (ESP) search for sign which can be used as a trigger when the ESP is finished. I guess there is a registry key when the ESP is finished. Just an idea. For triggering you have to be creative as well, maybe you find a good event or you do a busy-wait and let the scheduled task check every minute until it finds the state you want and then deletes itself (the scheduled task). I think you get the idea… During the past years I have done a lot of constructs like this, is is always a bit of research but 99% are these situations solved by a solution like this.
best,
Oliver
Hello Oliver. great article!!!. i have an issue were im getting this error for result details “Powershell execution has exceeded defined timeout.”. Im failing to understand why i keep getting this. Your help is greatly appreciated.
Hey Curibe,
the normal execution timeout of PowerShell Scripts is 1h. So did you had a look at the log file and compared the timestamps? Did it actually took longer than 1h?
best,
Oliver
Good content and amazing article. Small doubt, if end user is curious to know what is the app/msi name that has been deployed? Is there is way to find that from device/workstation perspective?
Everything in the registry and event viewer is GUIDs. But how would we know what is the name of the app or program that been deployed?
Hi Axle,
for the EnterpriseDesktopAppManagement CSP you will only find the MSI product code. Depending on the MSI you might have a uninstall entry here HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall where you can map the GUID to a display name, but this is dependent on he MSI, the MSI might not create the entry in every case.
An option is simply to compare the Add/Remove Programs in control panel to see what is installed but there is no display name list for this CSP.
For the Intune Management Extension, it does only log the app id in the registry under HKLM\Software\Microsoft\IntuneManagementExtension\Win32Apps\000….000\’app-id-goes-here’. The app id then can be looked up in the portal on the individual app in the URL. https://endpoint.microsoft.com/#blade/Microsoft_Intune_Apps/SettingsMenu/0/appId/'app-id-goes-here‘
best,
Oliver
Hi Oliver,
thanks for your detailed explanations.
Is there maybe a possibility to change the LastUpdateTime (or something like that) of scripts in Intune via Powershell to trigger the re-execution on clients?
I’m thinking of having a task running on a server, that regularly sets some parameter of the scripts in Intune to a newer value, so the clients will execute the scripts again on the next sync.
Do you have experience with that, or any info how to change the script parameters via powershell?.
Greetings, Oliver
Hey Oliver,
have a look a proactive remediations under Endpoint Analytics. With that you can easily execute scripts on a schedule, all built in. Give it a try first imho. https://docs.microsoft.com/en-us/mem/analytics/proactive-remediations?WT.mc_id=EM-MVP-5003177
best,
Oliver
Hi Oliver,
Very nice Article. We have print servers I created the powershell script to install the network printer on device. Because it is on network, I enabled the option to run as logged in user and assigned the policy on devices. The policy is succeeded printer installed. In case user removes the printer, after restart the Intune Extension service the script should run again and printer should be installed right?. Is the script not working as configuration policy? The other question regarding this is that I applied the policy on devices if three users login to the device the printer will be installed for all of them or after 1st success it will not run for other users?
Please, let me know Thanks.
Hi Shaak,
due to vacation some delay here.
The policy is succeeded printer installed. In case user removes the printer, after restart the Intune Extension service the script should run again and printer should be installed right?
=> no IME tracks the execution state and it is still tracked then as successful executed. IME restart will not change anything to this. a change of the script on the Intune service side would trigger a re-evaluation and re-execution.
The other question regarding this is that I applied the policy on devices if three users login to the device the printer will be installed for all of them or after 1st success it will not run for other users?
=> If you have a script checked with run as logged on user and scoped the assignment to a device group the script will run for every user who logs on to this particular machine.
I think your scenario could also be built with Endpoint Analytics and the proactive remediation scripting function. This will check if a condition is met and if not, it will run a remediation script to fix it. If you scope it to a user group it will run for every user in that group regardless on which device, they are logging in. If you scope it to a device group the script will run for the device.
best,
Oliver
Hi Oliver
Thanks for your article(s). They were a great help when I started using InTune and are still a great reference.
You mention in the article that you didn’t find any documentation about the 10′ script timeout. It has since been changed, as you probably know, to 30′. This is documented on this page https://docs.microsoft.com/en-us/mem/intune/apps/intune-management-extension
I believe the check-ins are roughly 1h apart. Quite infuriating that the time-out was changed without any way to customize it.
A recent “discovery” of mine is the following. I have not done more testing, but I’d like to dump it here, because I had not encountered this info before. I hope it is correct. The CSP appears to run scripts in a certain order. That order appears to be the alphabetic sort of the script ID! I just abused this by overwriting the script with the lowest sorted ID to ensure that a certain script gets run first on devices that have just been added to Azure AD.
Would love to hear your and others’ thoughts about this.
Hey Yan,
vacation brought some delays in replying, sorry. Yes, you are right with the 30 min. I changed it.
Your discovery is interesting and well observed. But(!) keep in mind that it can break as it is not an “official” use case how to leverage the system to ensure first run. If Microsoft changes the logic to look up the ideas in a different way you might get into trouble. I mean if you rely heavily on this and later on, they change something you can’t open up a support case for it to get some help.
best,
Oliver
Hello everyone, I have the same problem that is discussed below! After joining Azure Ad Intune, the Microsoft Intune Managenent extension service is not installed. I will tell you about this problem in more detail. I am using an enterprise Windows image 21H1 19043.1052 for installation. The image was created using sysprep /audit, and then sealed using sysprep /generalize. The task is to deploy this image on 200 machines and connect them to Azure AD, take control of Intune.There is no connection of machines to the local AD controller. When I deployed this image on the first machine and connected it to Azure AD, the machine connected correctly, the Microsoft Intune Management Extension service was installed and started correctly, all Win32 applications and policies come from Intune.Later, I deployed this image on five more test machines and connected them to Azure AD, they all have the same image: 1. The Microsoft Intune Management Extension Service is not installed. 2. In Intune, the machines are displayed strangely IRegistration_Windows_8/24/2021_9:55 am 3. In C:\ProgramData\Microsoft the IntuneManagementExtension 4 folder is missing. In the event viewer, Device Management-Enterprise Diagnostics 0 – Or errors 844, 76. This situation is observed on all other machines except the first one. There is a suspicion that Intune believes that this is a single machine, and does not install the Microsoft Intune Managenent extension service. It is not very clear which SID Intune binds to, and sysprep should have solved this problem. Please help me!!!
Hey Alex,
Did you also use /oobe for sysprep. That’s how I prepared images in the past successful. So, I used sysprep /oobe /reboot as the final step to get into the enrollment screen (OOBE). When I followed this approach, I never had issues like you described. Did you enroll via OOBE of within Windows Settings?
best,
Oliver