Windows Autopilot with User-Driven Hybrid Azure AD Domain Join using Palo Alto GlobalProtect VPN

UPDATE: Please also see part two on implementing Autopilot/GlobalProtect without certificates here:

Back in April, at the beginning of the pandemic, I started putting a lot of focus into getting Windows Autopilot to work with Hybrid Join clients and Microsoft Always On VPN. I was looking at both for different reasons but also looking at them as a combined solution. The issue with Autopilot was that technically you were still required to have line of sight to a domain controller even though the domain join happened via an offline blob using the on-prem Intune connector. Sifting through logs I could see the only thing holding back a successful enrollment was a little function at the end of enrollment that was simply looking for a domain controller. I was able to sometimes get an enrollment to work via device tunnel MS VPN policies, but success wasn’t consistent and relied on policies/certificates coming down in a timely manner. In the logging I also saw references to a configuration parameter that would disable the DC check. Soon after, I found a post from Microsoft saying that they had this setting in private beta and would be releasing it in the coming months. After this I decided to put everything on the backburner and abandon MS VPN (I found the MS VPN solution using RRAS to be clunky and inconsistent with a lot to be desired).

Fast forward a few months and Microsoft finally released the new ‘functionality‘. At its core it is really just a flag telling OOBE not to perform a DC connectivity check. After enrollment is completed you are on your own to establish pre-login connectivity to facilitate an initial logon to your domain as there are no cached credentials yet on the machine. We are already a Palo Alto GlobalProtect customer and have been happy with the solution, so getting the two to work together just made sense. At the same time there has also been a push to implement a proper Always On VPN configuration. I’ll be writing a post dedicated to the full technical and security architecture around a cert-based Palo Alto Always On VPN configuration, so I’ll only briefly touch on the relevant parts here. Please refer to Palo Alto documentation on the missing pieces. There are a number of security aspects that should be taken into account like revocation, key storage, etc., and you should already have a proper certificate authority. I am not going over those in this article. You should also already have configured your Autopilot profiles, Intune Connector for Active Directory, etc. as per this document.

In this configuration I use a certificate-only approach (only using certificate profiles and no other authentication methods) for both the portal and the gateway. Remember, our first GlobalProtect connection after an Autopilot enrollment will be a pre-logon connection via certificate. There are no other authentication methods available for this first connection and the portal -> gateway authentication flow needs to support this. Before configuration of the portal and gateway you need to configure zones, interfaces, policies, and a certificate profile. These steps are documented here (steps 1-3 and 5-6).

Below is the portal config. Notice how there are no client authentication methods present. If you were to add any method here, it would be layered on top of the certificate authentication and would prevent the pre-logon connection. PAN-OS 9.0 has implemented mixed authentication support so that you can implement an either/or type of configuration here. The other important note is that your user connection (post-logon) will be connecting to the same portal/gateway and because of this we will be using certificates for the user as well.

The next step is to configure the agent settings within the portal config. Our config is being configured as Always On, but this is not technically required for Autopilot to work. If you do not want an Always On user connection, set ‘Connect Method‘ to ‘Pre-logon then On-Demand‘. Some Palo-Alto documents mention using multiple agent configurations for pre-logon and post-logon that use different connect methods, but this is not necessary here (and will not always work as expected due to the order of operations). The other important thing is to set ‘Client Certificate Store Lookup‘ to ‘User and Machine‘ so that the client will be able to use user and device certificate. The client seems to do a good job at using the proper certificate depending on if the connection is pre-logon or post-logon.

After the portal you will configure the gateway. Authentication will be identical to the portal to allow for a seamless authentication flow.

To deliver a device certificate to the device we will use an Intune PKCS certificate profile. I won’t go into great detail here as Microsoft has done a good job of documenting the steps involved. The profile will need to be assigned to the device properly, and the easiest way to do this is by using an Azure AD dynamic group. I am using a custom EKU value in the screenshot below (Extended Key Usage) which you do not need to replicate. I had a specific reason for doing this.

You will also need to deliver a user certificate to the device. You can use another Intune PKCS certificate profile to do this or you can use GPO/User Certificate Autoenrollment. I chose the latter because I like the granular control it provides. If you use an Intune profile, but target the machine, every user that logs on to the machine will get a certificate and VPN access. If I target the user, every Intune-managed machine they log on to will get a user certificate. Both of these were undesirable. With autoenrollment I’m only enabling autoenrollment for the computers I want (using a user policy and loopback processing), and I’m controlling the users that can enroll/autoenroll via the ACL on the certificate template itself.

To get the GlobalProtect client deployed to our Autopilot device we will be using Intune to deploy it via a ‘Windows app (Win32)’ deployment. We need the Microsoft-Win32-Content-Prep-Tool utility, the GlobalProtect MSI (I am using version 5.1.5 at this time), and two wrapper scripts to complete the package.

The first wrapper script is InstallGlobalProtect.ps1. This is the one responsible for installing the MSI and pre-configuring some registry values. I thought this part would be very straightforward, but I had trouble getting the pre-logon credential provider to kick in initially when installing the client via Intune. If I manually installed the client, it worked the first time without an issue. It was only acting this way when being deployed via Intune during Autopilot. After a few hours of procmon traces and some reverse engineering of the client I figured out the issue. There is a post-setup process that runs that doesn’t process some registry changes correctly until the client is executed in the context of a user at least once. I use the wrapper to stage these two registry values (LogonFlag + LogonState) along with the others needed to make this configuration work. I also enable User-initiated Pre-Logon (via the ShowPrelogonButton value), so it gives the user a chance to verify they have internet connectivity and so that they can perform a retry of the pre-logon connection on demand. I later turn this off via GPO making pre-logon completely automatic after the first successful login. This value is totally optional.

The next wrapper script is a batch script that launches the script above. It is called InstallGlobalProtect.cmd. This script is needed because Intune will launch the installer in 32-bit mode and we want everything kicking off in 64-bit mode (mainly for the registry work above).

Once the three files are ready, we can create our package which generates a .intunewin file.

IntuneWinAppUtil.exe -c C:\Temp\GlobalProtectPackage\Install -s GlobalProtect64-5.1.5.msi -o C:\Temp\GlobalProtectPackage\Output

We then take this file and upload it to Intune to create our application. The application will need to be assigned to a group. Again, I am using a dynamic group that targets my Autopilot devices. As you can see below some of the MSI info is pulled in automatically because it was read by the Microsoft-Win32-Content-Prep-Tool utility. We must also change the ‘Install command‘ to point to the batch file we created earlier.

In testing I came across multiple issues due to machine GPO not being applied before the first login. One of these was loopback processing not applying which caused multiple user GPOs not to apply. Others were trusted root certs not installing (used for things like SSL decryption) and User Certificate Autoenrollment not working (I touched on this earlier). The trusted root issue actually caused my hybrid join to get stuck (SSL decryption is being used here). I decided to create IntuneHybridJoinHelperInstaller.ps1 to solve all of this.

IntuneHybridJoinHelperInstaller.ps1 does the following:

  • Creates a script directory (C:\Scripts)
  • Modifies the SACL of the directory to remove modify access from ‘Authenticated Users(someone could use this directory to execute malicious code in the context of ‘LOCAL SYSTEM‘ if you do not do this)
  • Create a script in the directory above called IntuneHybridJoinHelper.ps1 with an accompanying scheduled task that executes at any user logon in the context of ‘LOCAL SYSTEM

At the next logon, this newly deployed script is triggered by the scheduled task, checking to see if the computer group policy cache has ever been provisioned (has ever received computer policies) and if not it will do the following:

  • Perform a gpupdate for computer policies
  • Get the interactive logged on user
  • Create a task to run gpupdate as the currently logged on user which will perform a gupdate of their user policies
  • Re-run ‘Automatic-Device-Join‘ task to complete the device registration in case it failed at logon

It is best to deploy this as a Win32 app, like the GlobalProtect client, so that we can ensure it is on the machine before the first logon. Like GlobalProtect, we are using a batch wrapper (IntuneHybridJoinHelperInstaller.cmd) to launch the PowerShell script as a 64-bit process. I used the same dynamic group that I used for the GlobalProtect client as the target here. I also used a dummy uninstall command since we never need to ever uninstall this. For install detection I am just using the script path (C:\Scripts\IntuneHybridJoinHelperInstaller.ps1). We will build our package using the utility like we did for GlobalProtect.

IntuneWinAppUtil.exe -c C:\Temp\IntuneHybridJoinHelperInstaller\Install -s IntuneHybridJoinHelperInstaller.ps1 -o C:\Temp\IntuneHybridJoinHelperInstaller\Output

Now that we have everything in place we can test an enrollment. If everything is configured properly, you’ll be asked to sign-in to your corporate environment right after establishing network connectivity. After everything completes you should wind up at a logon screen. Because I am using User-initiated Pre-Logon I will need to switch to the GlobalProtect logon provider, click ‘Start GlobalProtect Connection’, and wait for the status to change to ‘Connected’.

After logging on you are presented with the User ESP (Enrollment Status Page). This is when our helper script kicks in to resolve GPO issues and moves our device registration along. This process can take a bit because after the ‘Automatic-Device-Join‘ completes you still have to wait for the on-prem computer object to sync up to Azure AD via AD Connect. Steve Prentice came up with a little script to help speed this up called SyncNewAutoPilotComputersandUsersToAAD.ps1. It just forces an AD Connect sync after computer object has its ‘userCertificate‘ attribute populated.

Once this is completed you should be left at a functioning desktop and GlobalProtect should have switched over to a full tunnel using the user certificate. At this point I would be using my primary endpoint management product, Ivanti Endpoint Manager, to perform any additional application installs/configurations. I have its agent being deployed via Win32 app as part of my Autopilot process.

63 thoughts on “Windows Autopilot with User-Driven Hybrid Azure AD Domain Join using Palo Alto GlobalProtect VPN

  1. Peter.Herbison

    I cannot believe how close to our current deployment scenario this is. And you’ve mentioned some things which definitely look like solutions to some of the problems we are currently experiencing trying to AutoPilot and Hybrid Join new devices. We too use the GlobalProtect client although we dont use machine or user certs, we use pre-logon user-authenticated (with MFA). Which we are finding little info on how to get it all to work with Autopilot.

    Thanks so much for posting all this. It will help us immensely.

  2. mwqawasmeh

    Hello Mark,

    Thank you for the detailed article!

    The configured certificate profile in the example “AlwaysOn-POC” is the same on both the Gateway and the portal. There you configured the certificate authority used to generate users and machines certificates imported on the firewall ?

    In the example, you used the same CA to generate both User and Machines certificates ?


    1. Mark DePalma Post author

      Yes, that is correct. I am using the same CA for both user and device certificates. On the CA though I am of course using different certificate templates for user and device. I am also using two different methods for deployment (Intune for device certificates and GPO for user certificates).

  3. SeanBcaw

    Hi Mark, awesome guide. I’ve almost got mine working, but I’m trying to do it without using your GPO method and just relying on Intune to deploy the User Certs… How do you target the local account Autopilot runs as (defaultuser0)?

    1. Mark DePalma Post author

      You can definitely use Intune to deploy the user certs. If you create a “PKCS certificate” profile with a “user” certificate type and target the computer (using a group) it will distribute a user certificate to anyone on that machine.

      You should not need a user cert for defaultuser0 though as the device cert/pre-logon tunnel takes care of this. The device cert/pre-logon tunnel are what let hybrid Autopilot work at all.

      1. SeanBcaw

        Ah I didn’t follow your instructions closely enough. I am deploying a SCEP certificate which is working fine for the Computer Cert, but not the User Cert… Do you know if SCEP is supposed to work for this purpose?

        1. Mark DePalma Post author

          Yes, you can use SCEP for user certs too, but you’ll need a second Intune profile for the user cert along with a user certificate template that it uses on the CA.

  4. Speedydowt

    Hi Mark,

    Great blog post, I just wanted to clarify the part where you say

    “Some Palo-Alto documents mention using multiple agent configurations for pre-logon and post-logon that use different connect methods, but this is not necessary here (and will not always work as expected due to the order of operations).”

    Does that mean to say that in your experience of this, setting up a pre-logon client configuration for pre user login based on certificates and then a user-logon client configuration using something like Azure AD with SAML authentication, would not work?

    Just wondered if we are tied to only being able to use user certificates for the user-logon part, or if its possible to use other authentication mechanisms like SAML for the user logon part.

    thanks again

    1. Mark DePalma Post author

      Agent configurations don’t *directly* relate to authentication configuration. You only have one authentication configuration for portal/gateway, but you can have multiple agent configurations per portal.

      The configuration you are referring to *would* need multiple agent configurations and multiple gateways if you wanted to properly segregate pre-logon and post-logon. You’d have have one portal configuration with two agent configurations. You would setup authentication on the portal to accept the certificate OR SAML using mixed authentication ( and then it would direct you to one of the two gateways depending on if you are pre-logon or post-logon. The pre-logon gateway would only accept certificate authentication and the post-logon gateway would only accept SAML. You would authenticate to portal, portal would determine if you are pre or post logon, and then portal would refer you to the appropriate gateway.

      The reason I am using one agent configuration in this example is because I am using certificate authentication for both phases (pre/post logon) and using a single gateway.


    @mark Thank you for this post, it really helped with the POC I was working on. I have a question for you, perhaps you may be able to help. Currently we are working with a Non-Production portal, which we are looking to use going forward for just the pre login and joining the organization. After first login or disconnect I would like to be able to switch the portal to our production portal, so when the users sign into the machine with their cache credentials all they will need to do is just choose their own gateway.

    Do you happen to have any recommendations as to how we can deploy / accomplish something like this?

    Thank you in advance.

    1. Mark DePalma Post author

      Sorry for getting to this late. What authentication method is the second portal going to use? Also, what is the reason for two different portals?

      1. Jessie

        Hi Mark, the reason for this question is because we have what we call our “Production (Site A)” gateway which everyone is the company is using. As part of our Hybrid Join scenario we created another gateway (Site B) for the pre-login and authentication portion. Once the autopilot goes through all it’s process and finishes, you are at the login screen again. At this point we want to be able to somehow Flip from Site B to Site A.

        So far I’ve done the following in order to do this but it isn’t perfect .

        As part of the global protect deployment (based on your article, thank you!) I’ve also added and extra line (See below) to the PowerShell script you provided and as a dependency there is a Win32app with a CMD Script

        #Post-vpn-connect I added these lines to InstallGlobalProtect.ps1

        New-Item -Path ‘HKLM:\SOFTWARE\Palo Alto Networks\GlobalProtect\Settings\’ -Name post-vpn-connect #-Force | Out-Null
        New-ItemProperty -Path ‘HKLM:\SOFTWARE\Palo Alto Networks\GlobalProtect\Settings\post-vpn-connect’ -Name “Command” -Value “c:\temp\GPFlip.cmd” -PropertyType “String”

        What this CMD script does is that it adds our production gateway at “Post-VPN-Connect” and then restarts the client, hence having the proper gateway configured so that our users can login. Up to this point things work well.

        THE PROBLEM…. is that I need to delete the “Post-VPN-Connect” key from the registry so that the script doesn’t run all over again. The last line is supposed to delete the key but unfortunately it does not.

        REM Script Name GPFlip.cmd
        REM Change Registry Gateway HKLM
        reg add “HKLM\SOFTWARE\Palo Alto Networks\GlobalProtect\PanSetup” /v Portal /t REG_SZ /d /f
        reg add “HKLM\SOFTWARE\Palo Alto Networks\GlobalProtect\Settings” /v LastUrl /t REG_SZ /d /f
        reg add “HKLM\SOFTWARE\Palo Alto Networks\GlobalProtect\PanSetup\PreLogonState” /v ConnectedGateway /t REG_SZ /d /f

        REM Change Registry Gateway HKCU
        reg add “HKCU\SOFTWARE\Palo Alto Networks\GlobalProtect\Settings” /v LastUrl /t REG_SZ /d /f

        REM Remove Registry
        reg delete “HKLM\SOFTWARE\Palo Alto Networks\GlobalProtect\Settings\” /f
        reg delete “HKCU\SOFTWARE\Palo Alto Networks\GlobalProtect\Settings\” /f

        REM Kill GlobalProtect App
        taskkill /im PanGPA.exe /f

        REM Delete Post VPN Connect
        reg delete “HKLM\SOFTWARE\Palo Alto Networks\GlobalProtect\Settings\post-vpn-connect” /f

        I also attempted to use a Runonce, but the only way this would work would be if the user reboots the machine and that isn’t a viable option. I hope I was clear in my explanation, and perhaps you or anyone here has a better solution that we can use, but we are in a bind at the moment on switching gateways.

        Thank you in advance.

        1. Jessie

          Just want to make a quick correction:

          REM Remove Registry
          reg delete “HKLM\SOFTWARE\Palo Alto Networks\GlobalProtect\Settings\” /f
          reg delete “HKCU\SOFTWARE\Palo Alto Networks\GlobalProtect\Settings\” /f

          1. Mark DePalma Post author

            The issue you are having is most likely because the script is running as the user (not as SYSTEM) and is trying to make system-level changes. I wouldn’t think any of your ‘HKLM\SOFTWARE\Palo Alto Networks\…’ changes are taking to be honest. Can you verify this?

          2. Jessie

            So once the user logs into their machine and get presented with GP, they log in Script runs, replaces the bits, GP reboots and again the user gets presented with GP portal Login (This part works great).

            What needs to happen next is, that I need to somehow delete the “post-vpn-connect” key that I created so that when the user logs in the second time it doesn’t run again. I figured that by adding this last line in my CMD it would work, but no luck.

            I’ve tested this scenario dozens of times, trying different methods, but this seems to be the most effective but with that small caveat.

          3. Mark DePalma Post author

            So an easier way to handle this is to just create a registry or file-based flag under the user’s profile at the end of the script (instead of the delete) and check that at the beginning of the script. If the script finds the flag just have it exit. You don’t really need to delete the whole value. This is the kind of logic ActiveSetup and other things use.

          4. Jessie

            Based on your suggestion, I attempted the following, but it ended up going in an endless loop. Perhaps I may have misinterpret what you suggestion.

            REM Script Name GPFlip.cmd

            REM Add registry key to detect
            echo GPFlipFlag > c:\GPFlipFlag.txt

            REM Change Registry Gateway HKLM
            reg add “HKLM\SOFTWARE\Palo Alto Networks\GlobalProtect\PanSetup” /v Portal /t REG_SZ /d /f
            reg add “HKLM\SOFTWARE\Palo Alto Networks\GlobalProtect\Settings” /v LastUrl /t REG_SZ /d /f
            reg add “HKLM\SOFTWARE\Palo Alto Networks\GlobalProtect\PanSetup\PreLogonState” /v ConnectedGateway /t REG_SZ /d /f

            REM Change Registry Gateway HKCU
            reg add “HKCU\SOFTWARE\Palo Alto Networks\GlobalProtect\Settings” /v LastUrl /t REG_SZ /d /f

            REM Remove Registry
            reg delete “HKLM\SOFTWARE\Palo Alto Networks\GlobalProtect\Settings\” /f
            reg delete “HKCU\SOFTWARE\Palo Alto Networks\GlobalProtect\Settings\” /f

            REM Kill GlobalProtect App
            taskkill /im PanGPA.exe /f

            REM Delete Post VPN Connect
            reg delete “HKLM\SOFTWARE\Palo Alto Networks\GlobalProtect\Settings\post-vpn-connect” /f

            REM Detect registry created in HKCU to stop script
            if exist “c:\GPFlipFlag.txt” ( exit )

          5. Mark DePalma Post author

            Your last line needs to be moved all the way up to the beginning. You need to START with the detect so you can exit before doing anything.

          6. Jessie

            Mark, thank you so much for your help. Your suggestions helped me out a great deal. Truly thank you.

  6. emiranda

    Great blog post. There is not much documentation out there on this and this post helped out a lot. Thank you! One thing I had to modify since you may have posted. The newer GP software is 64bit. In order to add those registry keys, you will have to add this to your powershell script to get the keys added in the 64bit hive (since Intune defaults running PS in 32bit mode).

    if (“$env:PROCESSOR_ARCHITEW6432” -ne “ARM64”)
    if (Test-Path “$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe”)
    & “$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe” -ExecutionPolicy bypass -NoProfile -File “$PSCommandPath”
    Exit $lastexitcode

    1. Mark DePalma Post author


      This was covered in the post (search for “64-bit mode”). This is what this CMD wrapper was for: The CMD wrapper executes PS using the SysNative location which executes in 64-bit on a 64-bit machine.

      The flow is:

      Intune Win32 App Install -> InstallGlobalProtect.cmd -> InstallGlobalProtect.ps1

      I’m happy this post was helpful for you!

  7. Garthlogic

    Sure do appreciate this post. I’m still having issues in that the pre-login (and the VPN software in general) does not work until I run the app in user context first (i.e. launch from Start Menu). and I’ve verified the creation of those registry entries too. Thoughts?

    1. Mark DePalma Post author

      If you have verified that all the registry entries are there, I’m not sure what the issue could be. What exactly happens? Does the GlobalProtect credential provider (the little box next to the other logon methods) show at all? Does it show, but just doesn’t do anything?

  8. jambo6581

    Hi Mark,

    I may be way off the mark here but can you not setup the install using the 64 msi installer in ‘line of business apps’ instead of win32 apps?

    1. Mark DePalma Post author

      LoB apps expect an MSI only along with a transform, no scripts or anything else. When we do a Win32 app we are packaging in a way where it performs all of the other actions we needed. You have a lot more customization. Another thing is we are using our Intune ‘wrapper’ script which can only be deployed using the Win32 method. Microsoft advises that you only use Win32 OR LoB for apps during Autopilot and not a mix. There are also other things like detection rules that you gain with the Win32 method.

      1. jambo6581

        Perfect, thank you Mark. I am currently setting up autopilot and this article is very helpful.
        MSP that we work with have advised that we set it up SCEP though and not use PKCS in a hybrid environment…

  9. Intuneforwork

    Hi Mark,
    Thank you so much for this article. This is very helpful.
    I need your help, if I am doing this right.

    1. I have SCEP configured as Device type certificate and assigned to device group. Would it be enough orwith just this device type cert to make it work? (or should I also need to deploy User type cert)
    2. As in the blog, If I just wrap our Global Protect MSI app with your InstallGlobalProtect.ps1 and InstallGlobalProtect.cmd and deploy as Win32 would that be enough or should I also need to deploy IntuneHybridJoinHelperInstaller.ps1. (I am looking for simple configuration to make this pre-logon work and not to use GPO)

    I really appreciate how you are helping so many people on this blog. You are a savior.

    1. Mark DePalma Post author


      1.) You *can* make this all work with a device certificate only but I would recommend also issuing and using a user certificate. The ideal configuration involves the pre-logon (device certificate) tunnel having restricted network access and then the user tunnel elevating to some sort of “full” access. You’d want the pre-logon tunnel to only have access to necessary hosts like domain controllers and endpoint protection servers.

      2.) If you are are not concerned with group policy functioning at the first logon then you can probably do without the helper script. There is a line in the helper script that assists with completing the hybrid join process (if it did not complete) if that is working for you without the helper script then you can forgo it.

      Thank you! I’m glad this article was helpful!

      1. Intuneforwork

        Thank you for your response.
        Don’t we need to deploy VPN configuration profile
        from Intune(MDM) to make this work?
        Where we set the Base VPN details like connection type, Always On Enable, selecting the Auth cert

        1. Mark DePalma Post author

          It depends on what VPN solution you are using. In this post I am using GlobalProtect, so there is no VPN profile needed. GlobalProtect will set everything up as per the article. If you are using MS RRAS then you would need to create and deploy VPN profiles.

          1. Intuneforwork

            I am very close to make this work but not sure where I am failing.. I have deployed just the trusted root and SCEP device type cert targeted to device group..

            As per your article, I have just used the Globalprotect app packed with the PS script and batch file..

            On the device, the Autopilot triggers, everything goes smooth. Whn I am at Windows login page, I am even able to see the Start GlobalProtect Connection button. But once I click on it, tries to connect for a second and says disconnected 🙁

          2. Mark DePalma Post author

            Try clicking it a few times if you haven’t (just in case). Also, make a backdoor admin account on the machine so that you can login and look at logs. I had to do this to troubleshoot early on. You’d really need to look at the PanGPS.log file to see what is happening, that is where I did a lot of my troubleshooting… Obviously you can verify the cert is actually installed properly at this time also.

  10. newpotatoe

    We are using global protect and Certificate based authentiication for the VPN connectivity to autopilot Hybrid join. Can we deploy the device cert using scep profile but without deploying the ndes server.

    1. Mark DePalma Post author

      You need an NDES server for SCEP, that is how SCEP works. If you don’t want to go that route you can do PKCS using only the Intune connector.

  11. Intuneforwork

    Hi Mark,
    We used PKCS cert and it got depoyed successfully.. We can see that cert in the device too..
    We are able to see the sign in option, connect to GlobalProtect Icon..
    However, the connection is still failing.. As soon as we click on start connect, The global protect status says disconnected.

    I see that you have inforemd to look into PanGPS.log.. any guidance on what I should be looking into and how to troubleshoot this.

    Please help!

    1. Mark DePalma Post author

      You’d have to comb through the log and look for the failure reason. Another thing you can do that might be easier to start with is look at the GlobalProtect logs on the actual firewall. Look for the connection attempt/failure there first.

  12. Pingback: Windows Autopilot with User-Driven Hybrid Azure AD Domain Join using Palo Alto GlobalProtect VPN: Part 2, using GlobalProtect PLAP with Basic Credentials | Maniacal Methods

  13. waple02

    Hi There, I’ve found you website that is related to my project, what I want to achieve is to deploy the global protect to the client with the VPN address injected. I’ve followed the 1st face your instruction. Converting the global protect installer into intunewin file. II can abled to install the app by using this command installGlobalProtect.cmd from intune, but the vpn address wasn’t injected to the client. Do you have any suggestions?

    Thank you in advance.

    1. Mark DePalma Post author

      Did you include the registry lines in the PowerShell script? The one line there were s the portal.

      This line below specifically… You also need to edit the $PortalAddress at the top with your portal address.

      New-ItemProperty -Path ‘HKLM:\SOFTWARE\Palo Alto Networks\GlobalProtect\PanSetup’ -Name ‘Portal’ -Value $PortalAddress -PropertyType String -Force | Out-Null

  14. aeroplane9

    Hi Mark,
    Thanks a heap for this managed to get it working in our environment. However, some time has passed and now we’ve noticed at the end of the process the ‘Start Global Protect Connection’ link/button doesn’t work. Once we perform a restart it starts working as per normal going forward. Have you ever run into this?

        1. Mark DePalma Post author

          Interesting. Clicking the button more than once also doesn’t connect? Can you pull the PanGPS.log file to see what it reports for that first attempt?

  15. waple02

    I’ve followed your instruction and the agent was able to installed . But the vpn addres is not push to the client.

    $PortalAddress = ‘’
    $MSIFileName = ‘GlobalProtect64-5.1.5.msi’
    $MSISwitches = ‘/quiet /norestart’

    $ScriptPath = Split-Path -Path $MyInvocation.MyCommand.Path

    $InstallProcess = Start-Process -FilePath “msiexec” -ArgumentList (“/i ” + [char]34 + $ScriptPath + “\” + $MSIFileName + [char]34 + ” ” + $MSISwitches) -PassThru -Wait

    New-Item -Path ‘HKLM:\SOFTWARE\Palo Alto Networks\GlobalProtect\PanSetup’ -Name ‘PreLogonState’ -Force | Out-Null
    New-ItemProperty -Path ‘HKLM:\SOFTWARE\Palo Alto Networks\GlobalProtect\PanSetup\PreLogonState’ -Name ‘LogonFlag’ -Value 0 -PropertyType Dword -Force | Out-Null
    New-ItemProperty -Path ‘HKLM:\SOFTWARE\Palo Alto Networks\GlobalProtect\PanSetup\PreLogonState’ -Name ‘LogonState’ -Value 0 -PropertyType Dword -Force | Out-Null
    New-ItemProperty -Path ‘HKLM:\SOFTWARE\Palo Alto Networks\GlobalProtect\PanSetup’ -Name ‘Portal’ -Value $PortalAddress -PropertyType String -Force | Out-Null


    %SystemRoot%\SysNative\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass .\InstallGlobalProtect.ps1


    1. Mark DePalma Post author

      Did you check to see if the actual registry values were set? Also you have a mixture of the batch file and PowerShell script here, they are two separate scripts.

  16. theFulton

    Hiya Chaps and Thanks to Mark for putting this together, i am having similar issues, The PLAP part 2 way works no probs but this way (which is what i need) does not.
    I get the click to connect button once the build finishes but it does nothing, repeated clicking connect does nothing and if i walk away and come back the lock screen locks, and the start connection box has then vanished . I am certain i have followed all correct steps, please advise.

    1. Mark DePalma Post author

      The first step in troubleshooting would be to look at your PanGPS.log file for errors. Pull that and see what it is saying at the time of connection.

      1. theFulton

        Hey mark, thanks. But i cannot login to the device to get accees to the logs, but what we can see from PA side is that the device is redirecting to to auth ?
        weird huh. i didnt use the intune helper as we have deployed the certs via intune, scep and pki’s

        1. Mark DePalma Post author

          The is probably part of the Azure AD auth and not related to this. You need to create a temporary Intune profile that creates a backdoor admin account so you can get in and pull the log file. That is the only way you can troubleshoot why it isn’t connecting.

          1. Mark DePalma Post author

            No problem! Let me know if you have any questions on the log. I had to do the same in my early testing. The backdoor account was the only way for me to debug issues.

  17. DaveE

    Hello Mark

    Was wondering where you got the extended Key usage PA GP VPN Certificate.? Where do we find this .
    We have created the application in Intune and added them to the group for autopilot for hybrid join.

    Any info would be appreciated.


    1. Mark DePalma Post author

      Good question. In this case I added a custom EKU to the certificate template we were using. I had a specific reason where I needed to filter certs, but normally you don’t have to do this. You can use a custom EKU in the Palo Alto agent settings to force it to use/submit a specific certificate.

      This is where I created the EKU in the template:
      Custom EKU

  18. Gemack

    I have one question. How does Intune know where the scripts are located (i.e. InstallGlobalProtect.cmd)? I have all of this working prior to looking at thias article and want to understand where these scripts are stored for Intune to call? I know there is a “scripts” section and want to know if this is where these .ps1 and cmd file get uploaded.

    1. Mark DePalma Post author

      The location is part of the agent that gets put on the machine, but the location of the scripts really doesn’t matter. The way I wrote the wrapper the wrapper knows it’s location and then can reference things in that same location dynamically.

  19. Pingback: Quick Tip: Hybrid Domain Join with Intune –

Leave a Reply