Blog Post

Core Infrastructure and Security Blog
11 MIN READ

Introducing Certificate Template API

NoMoePwds's avatar
NoMoePwds
Icon for Microsoft rankMicrosoft
Jan 24, 2020

First published on TECHNET on Sep 25, 2009

WARNING: USE OF THE SAMPLE CODE PROVIDED IN THIS ARTICLE IS AT YOUR OWN RISK. Microsoft provides this sample code "as is" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.

 

In this post I would like to talk about how a developer can package a certificate template as a resource in their application to be later installed in a customer environment. This post assumes that you have good understanding of the Enterprise CAs, certificate templates, and Active Directory.

 

Here is one possible scenario. Let’s say your application uses a certificate for communication between its client and server components. You have specific requirements as to what that certificate should look like. Your application is meant to work in Windows environment so you want to take advantage of Windows CA and autoenrollment and have CA issue certificates for you clients so you don’t have to worry about the certificate enrollment yourself. But how do you configure CA and more importantly certificate template from your code? Before Windows Server 2008 R2 your only solution to those is to provide documentation for your admins on how to do it manually or go directly to AD using LDAP and modify certificate template objects (this option is a hack and not supported by the way).

 

In Windows Server 2008 R2 and Windows 7 we’ve added an API that will let developers to do the template setup in code in a supported way. As a developer you will actually need a Windows Server 2008 R2 installation in your test environment to create your resource, but your application can run on either Windows Server 2008 R2 or Windows 7. This will become clear as I go through the steps in this post.

 

First, a little historical perspective to understand why going directly to AD to modify certificate templates is not supported. Certificate templates have been around for a while and were not even customizable originally. When customization was added a lot of rules about what settings make sense were implemented in the certificate template MMC snap-in (certtmpl.msc). For example, you can only select to archive a private key on a certificate template that has encryption purpose. There are many more rules like that. These rules ensured that certificate templates are always “good” and allowed some assumptions to be made in the code that actually used the templates. Hence, we don’t want others to mess with certificate templates outside of our snap-in. However, as the number of applications that used certificates grew, we started receiving request to programmatically create certificate templates.

 

So how do you do it? At the very high level the process looks like this:

 

At the development time:

 

1. Setup a test MS PKI environment including a DC, CA, Certificate Enrollment Policy Service, and Certificate Enrollment Service.

 

2. Configure a template as desired.

 

3. Export a template.

 

4. Include exported template in your application and develop a code that will import it at the execution time.

 

At the setup execution time

 

1. Import exported template to your customer’s AD environment.

 

2. Configure a CA to issue a template.

 

Development Time

 

Most of the work will have to happen during development (more importantly all of the manual work).

 

Environment Setup

 

Before you can create and export a certificate template, you need to setup a proper environment. You need only one Windows Server 2008 R2 machine for that.

 

First of all, we need an Enterprise CA and of course a DC because templates are stored in Active Directory. Don’t worry about the names you use for you CA, DC, or domain. None of that stuff will be exported by our API.

 

Then you need to setup Certificate Enrollment Policy Service and Certificate Enrollment Service. These are new role services for the ADCS server role in Windows Server 2008 R2. To learn more about these role services see this page . The reason we need them is because we want to leverage the XML that they produce to export our template.

 

Template Configuration

 

Now configure a template that you application needs by duplicating one of the default templates. Don’t bother with the security settings (more on that later) except for making sure that your test user account that you are going to use during export has Read and Enroll permissions on the template. If you need more than one template, configure them as well. Our API can handle exporting/importing of multiple templates.

 

Once you have configured the template(s), add it for issuance on your CA and remove all other templates. This will ensure that you only export what you need.

 

Exporting a Template

 

You need to write a little code to export a template. This code doesn’t need to be included in the actual application since the application only requires the import. Here is sample code that exports templates to a file:

 


   1: //
   2: // exports template from a policy server and saves the data
   3: // into some file. Defaulting to a user context and kerb auth. 
   4: //
   5: static void Export(string policyServerURL, string fileName)
   6: {
   7:     //
   8:     // Get template data from policy server
   9:     //
  10:     IX509EnrollmentPolicyServer policyServer = new CX509EnrollmentPolicyWebServiceClass();
  11:     policyServer.Initialize(
  12:         policyServerURL, 
  13:         null, 
  14:         X509EnrollmentAuthFlags.X509AuthKerberos, 
  15:         false, 
  16:         X509CertificateEnrollmentContext.ContextUser
  17:         );
  18:     policyServer.SetCredential(0, X509EnrollmentAuthFlags.X509AuthKerberos, null, null);
  19:     policyServer.LoadPolicy(X509EnrollmentPolicyLoadOption.LoadOptionReload);
  20:  
  21:     //
  22:     // export template data and save it to a file
  23:     //
  24:     byte[] exportedData = (byte[])policyServer.Export(
  25:         X509EnrollmentPolicyExportFlags.ExportOIDs | X509EnrollmentPolicyExportFlags.ExportTemplates
  26:         );
  27:     using(FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
  28:     {
  29:         fs.Write(exportedData, 0, exportedData.Length);
  30:     }
  31: }

 

 

 

Although, the APIs are documented in the MSDN , I will add few words on the parameters and the general flow of the code here.

 

First we create an instance of an object that implements IX509EnrollmentPolicyServer interface and represents a Certificate Enrollment Policy Service. We initialize it with its URL that you can get from the IIS snap-in -> Default Web Site -> properties of an application that has “PolicyProvider_CEP” in its name. The AuthFlags are set based on the authentication option you chose during Certificate Enrollment Policy Service setup. I’ve used Kerberos here as this the easiest one to deal with. The Context parameter is set to ContextUser so make sure you ACL template so that the user account executing this code has access.

 

Then we call SetCredential() method with a X509EnrollmentAuthFlags.X509AuthKerberos type. No other parameters need to be set as this type uses Windows Integrated authentication.

 

After that we call LoadPolicy() which actually retrieve the Certificate Enrollment Policy Service end point. We use X509EnrollmentPolicyLoadOption.LoadOptionReload to avoid caching. More on that later.

 

Finally we export the template data and associated OID objects and write them to a file. Later we can package that file into our application for import at the run time.

 

A word of caution on caching… If you’re playing with a template by changing its properties and trying to export it, there several caches that you should be aware of. First the cache that the APIs maintain on each client. That cache can be avoided by passing X509EnrollmentPolicyLoadOption.LoadOptionReload option to the LoadPolicy() method call as I have done above. Second cache exists on the Certificate Enrollment Policy Service side. To avoid this cache go to the IIS manager snapin -> Default Web Site -> *CEP* -> Application Setting and create a RetryIntervalMs application setting and set it to something small like 1000. This makes policy service to refresh its cache every second.

 

Execution Time

 

There are several tasks that you would need to do at the setup and uninstall time.

 

Setup

 

During setup process, you want to load the exported template data and import it into your customer’s Active Directory. Here is a sample code that does that:

 


   1: //
   2: // Read exported template data from the file
   3: //
   4: static void Import(string fileName)
   5: {
   6:     //
   7:     // read exported template data from a file
   8:     //
   9:     byte[] importedData = null;
  10:     using(FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None))
  11:     {
  12:         importedData = new byte[fs.Length];
  13:         fs.Read(importedData, 0, importedData.Length);
  14:     }
  15:  
  16:     //
  17:     // Initialize policy server interface with exported data instead of connecting
  18:     // to a real policy server
  19:     //
  20:     IX509EnrollmentPolicyServer importPolicyServer = new CX509EnrollmentPolicyWebServiceClass();
  21:     importPolicyServer.InitializeImport(importedData);
  22:     
  23:     //
  24:     // go through each imported template, set its security descriptor, and 
  25:     // write it to Active Directory
  26:     //
  27:     IX509CertificateTemplates templates = importPolicyServer.GetTemplates();
  28:     foreach (IX509CertificateTemplate template in templates)
  29:     {
  30:         IX509CertificateTemplateWritable writableTemplate = new CX509CertificateTemplateADWritableClass();
  31:         writableTemplate.Initialize(template);
  32:         writableTemplate.set_Property(EnrollmentTemplateProperty.TemplatePropSecurityDescriptor, SDDL);
  33:         writableTemplate.Commit(CommitTemplateFlags.CommitFlagSaveTemplateGenerateOID, null);
  34:     }
  35: }
  36:  
  37: private const string SDDL = 
  38:     "O:EA" + //owner is Enterprise Admins
  39:     "G:EA" + //group is EA as well
  40:     "D:PAI" + //DACL with SE_DACL_PROTECTED and SE_DACL_AUTO_INHERITED 
  41:     "(OA;;CR;a05b8cc2-17bc-4802-a710-e7c15ab866a2;;DU)" + //autoenroll for Domain Users
  42:     "(OA;;RPWPCR;0e10c968-78fb-11d2-90d4-00c04f79dc55;;DA)" + //enroll for Domain Admins
  43:     "(OA;;RPWPCR;0e10c968-78fb-11d2-90d4-00c04f79dc55;;DU)" + //enroll for Domain Users
  44:     "(OA;;RPWPCR;0e10c968-78fb-11d2-90d4-00c04f79dc55;;EA)" + //enroll for Enterprise Admins
  45:     "(A;;CCDCLCSWRPWPDTLOSDRCWDWO;;;DA)" + //all access to Domain Admins
  46:     "(A;;CCDCLCSWRPWPDTLOSDRCWDWO;;;EA)" + //all access to Enterprise Admins
  47:     "(A;;LCRPLORC;;;AU)"; //read for Authenticated Users

 

First we read the exported data from the same file we used in the export sample.

 

Then we create an instance of an object that implements IX509EnrollmentPolicyServer and initialize it with data we have read from the file earlier. This time we don’t actually need to call LoadPolicy() method or set the authentication parameters since we don’t need to retrieve the data from the actual Certificate Enrollment Policy Service endpoint.

 

Finally, we iterate through the template collection and for each template in the collection we create an instance of the writable template object. These objects can actually we written to the Active Directory.

 

However, before we actually commit the write operation, we need to set the security descriptor property. This property is not exported (it doesn’t make sense to export it actually since it would be meaningless outside of the test environment we’ve used to create a template) and if you don’t set it you will inherit a default setting that would only allow enrollment for your domain admins. Note that at this time you can’t change other properties besides security descriptor.

 

When we call Commit() method to complete the write operation, we pass the CommitFlagSaveTemplateGenerateOID flag to tell the API to generate an OID for us similar to what the duplicate action does in the certificate template snap-in.

 

Note that in order for you to add a certificate template, you need write permissions to the Configuration\Services\Public Key Services AD container which in default setup means Enterprise Admins membership.

 

If you have created custom application policies (aka EKUs) in your test environment by going to the Extensions tab -> Edit -> Add… -> New…, you would need to install those in the customer environment using certutil.exe since the API at this time doesn’t support importing those. Here is how you would do it:

 



Certutil.exe -f -oid 1.2.3.4.5.6.7.8.9.0 MyEKU 1033 3


What this command does is registers your EKU in Active Directory. We use -f switch to allow certutil.exe to create new object. Then we provide the OID value and the display name. The 1033 is the language ID that will be used by the certificate UI when it encounters this OID in a certificate. For a list of language IDs see this MSDN page . The last parameter specifies the type of OID object we are creating which is the Application Policy type.

 

To check that registration has been successful in your code just check the return code from certutil.exe. Manually you can run this command:

 


C:\>certutil.exe -v -oid 1.2.3.4.5.6.7.8.9.0
System default Language Id:: 409 (1033)
1.2.3.4.5.6.7.8.9.0 – MyEKU
pwszName = MyEKU
CRYPT_ENHKEY_USAGE_OID_GROUP_ID (7)
dwValue = 0
0: 1033,TestEKU2
CertUtil: -oid command completed successfully.

 

Once you have certificate template setup you can use ICertAadmin2::SetCAProperty() method to add your template to be issued by a CA. Here is a sample code on how to do it:

 


   1: static void AddTemplateToCA(string templateName, string templateOid)
   2: {
   3:     //
   4:     // let user to pick a CA
   5:     //
   6:     ICertConfig2 certConfig = new CCertConfigClass();
   7:     string caConfig = certConfig.GetConfig(0x1 /* CC_UIPICKCONFIG */);
   8:  
   9:     //
  10:     // get current templates that are configured on the CA 
  11:     //
  12:     ICertAdmin2 admin = new CCertAdminClass();
  13:     StringBuilder sb = new StringBuilder(
  14:         (string)admin.GetCAProperty(caConfig, 29 /* CA_PROP_TEMPLATES */, 0, 4 /*string*/, 0)
  15:         );
  16:     
  17:     //
  18:     // add new template to the list and update the CA
  19:     //
  20:     sb.Append(templateName);
  21:     sb.Append("\n");
  22:     sb.Append(templateOid);
  23:     sb.Append("\n");
  24:     object newTemplates = sb.ToString();
  25:     admin.SetCAProperty(caConfig, 29, 0, 4, ref newTemplates);
  26: }

 

This method takes two parameters the template name and template OID. It is obvious where we get the template name (we created it at the development time), but where is the application can get the OID. You can record it right after you wrote the template to AD by calling the GetProperty() method with the EnrollmentTemplateProperty.TemplatePropOID flag.

 

Now let’s look at what the code does. First, we use ICertConfig::GetConfig() method to prompt a user to select a CA. Then we query for a currently configured list of templates from that CA. Finally, we modify the list by adding our template to the end of it and by setting the list back on the CA. You need to be an admin on the CA for this code to run.

 

Uninstall

 

When your application performs uninstall you need a way to delete a template and/or OIDs that you have created during setup.

 

The OID deletion is simple and can be achieved by this certutil.exe command:

 


Certutil.exe -oid 1.2.3.4.5.6.7.8.9.0 delete

 

To remove a template from a CA, you can use ICertConfig2::Next() method to iterate through all enterprise CAs and use ICertAdmin2 interface to find which CA has your template configured. Removing it from a CA is a reverse operation from what we did in the AddTemplateToCA() sample code earlier.

 

The deletion of a template is a little bit more involved. Here is a sample code to do it:

 




   1: //
   2: // Delete a template identified by templateCommonName paramter from AD
   3: // using a DC specified by dcDnsName parameter
   4: //
   5: static void Delete(string templateCommonName, string dcDnsName)
   6: {
   7:     //
   8:     // Get templates from AD
   9:     //
  10:     IX509EnrollmentPolicyServer adPolicyServer = new CX509EnrollmentPolicyActiveDirectoryClass();
  11:     adPolicyServer.Initialize(
  12:         dcDnsName, 
  13:         null, 
  14:         X509EnrollmentAuthFlags.X509AuthKerberos, 
  15:         false, 
  16:         X509CertificateEnrollmentContext.ContextUser
  17:         );
  18:     adPolicyServer.LoadPolicy(X509EnrollmentPolicyLoadOption.LoadOptionReload);
  19:     IX509CertificateTemplates templates = adPolicyServer.GetTemplates();
  20:     
  21:     //
  22:     // go through each template and if a match found delete from AD
  23:     //
  24:     foreach (IX509CertificateTemplate template in templates)
  25:     {
  26:         string currentTemplateCommonName = 
  27:             (string)template.get_Property(EnrollmentTemplateProperty.TemplatePropCommonName);
  28:  
  29:         if (0 == String.Compare(currentTemplateCommonName, templateCommonName, true))
  30:         {
  31:             IX509CertificateTemplateWritable writableTemplate = new CX509CertificateTemplateADWritableClass();
  32:             writableTemplate.Initialize(template);
  33:             writableTemplate.Commit(CommitTemplateFlags.CommitFlagDeleteTemplate, dcDnsName);
  34:             break;
  35:         }
  36:     }
  37: }

 

This code looks very similar to the import case. First we create IX509EnrollmentPolicyServer instance only this time we use a CX509EnrollmentPolicyActiveDirectoryClass class. Then we get all of the templates currently in AD and go through that collection until we find the one we looking for. Once we find it we delete by calling the Commit() method with the CommitFlagDeleteTemplate flag. You need to have the delete permission on the Configuration\Services\Public Key Services AD container (specifically Certificate Templates container and OID container) for the deletion to succeed.

 

In my sample I’m specifying a DC name that I want APIs to work with. This is not required. You can just pass null to get a default DC. However, it is a good general practice to use a specific DC to get consistent results. Otherwise different method invocations can actually be performed against different DCs and you may run into problems with AD data not being consistent across DCs you are using.

Updated Feb 21, 2020
Version 3.0

1 Comment

  • Sundance's avatar
    Sundance
    Copper Contributor

    This is truly useful. But I am having a problem with the export function.  For one thing, I am not sure what to pass in as the policyServerURL.  At the moment,  I am using the fully qualified name of my domain controller, which happens to also be the Certification Authority. Is it correct?  Still on the Export call ((byte[])policyServer.Export etc...) I get a NOT IMPLEMENTED (80004001)exception.  Any idea what I am doing wrong? I am running on a Server 2016 machine. Enterprise CA.  I don't have issues running the other functions.

     

"}},"componentScriptGroups({\"componentId\":\"custom.widget.MicrosoftFooter\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"components/community/NavbarDropdownToggle\"]})":[{"__ref":"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/QueryHandler\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageCoverImage\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageCoverImage-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeTitle\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeTitle-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTimeToRead\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTimeToRead-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageSubject\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageSubject-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserLink\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserLink-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserRank\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserRank-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTime\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTime-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageBody\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageBody-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageCustomFields\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageCustomFields-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageRevision\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageRevision-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageReplyButton\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageReplyButton-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageAuthorBio\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/ranks/UserRankLabel\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserRegistrationDate\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserRegistrationDate-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeAvatar-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeDescription\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeDescription-1745505309806"}],"message({\"id\":\"message:3693043\"})":{"__ref":"BlogReplyMessage:message:3693043"},"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"components/tags/TagView/TagViewChip\"]})":[{"__ref":"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1745505309806"}],"cachedText({\"lastModified\":\"1745505309806\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeIcon\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1745505309806"}]},"CachedAsset:pages-1745487429407":{"__typename":"CachedAsset","id":"pages-1745487429407","value":[{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"BlogViewAllPostsPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId/all-posts/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"CasePortalPage","type":"CASE_PORTAL","urlPath":"/caseportal","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"CreateGroupHubPage","type":"GROUP_HUB","urlPath":"/groups/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"CaseViewPage","type":"CASE_DETAILS","urlPath":"/case/:caseId/:caseNumber","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"InboxPage","type":"COMMUNITY","urlPath":"/inbox","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"HelpFAQPage","type":"COMMUNITY","urlPath":"/help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"IdeaMessagePage","type":"IDEA_POST","urlPath":"/idea/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"IdeaViewAllIdeasPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/all-ideas/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"LoginPage","type":"USER","urlPath":"/signin","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"BlogPostPage","type":"BLOG","urlPath":"/category/:categoryId/blogs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"UserBlogPermissions.Page","type":"COMMUNITY","urlPath":"/c/user-blog-permissions/page","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"ThemeEditorPage","type":"COMMUNITY","urlPath":"/designer/themes","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"TkbViewAllArticlesPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId/all-articles/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730142000000,"localOverride":null,"page":{"id":"AllEvents","type":"CUSTOM","urlPath":"/Events","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"OccasionEditPage","type":"EVENT","urlPath":"/event/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"OAuthAuthorizationAllowPage","type":"USER","urlPath":"/auth/authorize/allow","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"PageEditorPage","type":"COMMUNITY","urlPath":"/designer/pages","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"PostPage","type":"COMMUNITY","urlPath":"/category/:categoryId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"ForumBoardPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"TkbBoardPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"EventPostPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"UserBadgesPage","type":"COMMUNITY","urlPath":"/users/:login/:userId/badges","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"GroupHubMembershipAction","type":"GROUP_HUB","urlPath":"/membership/join/:nodeId/:membershipType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"MaintenancePage","type":"COMMUNITY","urlPath":"/maintenance","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"IdeaReplyPage","type":"IDEA_REPLY","urlPath":"/idea/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"UserSettingsPage","type":"USER","urlPath":"/mysettings/:userSettingsTab","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"GroupHubsPage","type":"GROUP_HUB","urlPath":"/groups","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"ForumPostPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"OccasionRsvpActionPage","type":"OCCASION","urlPath":"/event/:boardId/:messageSubject/:messageId/rsvp/:responseType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"VerifyUserEmailPage","type":"USER","urlPath":"/verifyemail/:userId/:verifyEmailToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"AllOccasionsPage","type":"OCCASION","urlPath":"/category/:categoryId/events/:boardId/all-events/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"EventBoardPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"TkbReplyPage","type":"TKB_REPLY","urlPath":"/kb/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"IdeaBoardPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"CommunityGuideLinesPage","type":"COMMUNITY","urlPath":"/communityguidelines","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"CaseCreatePage","type":"SALESFORCE_CASE_CREATION","urlPath":"/caseportal/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"TkbEditPage","type":"TKB","urlPath":"/kb/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"ForgotPasswordPage","type":"USER","urlPath":"/forgotpassword","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"IdeaEditPage","type":"IDEA","urlPath":"/idea/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"TagPage","type":"COMMUNITY","urlPath":"/tag/:tagName","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"BlogBoardPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"OccasionMessagePage","type":"OCCASION_TOPIC","urlPath":"/event/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"ManageContentPage","type":"COMMUNITY","urlPath":"/managecontent","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"ClosedMembershipNodeNonMembersPage","type":"GROUP_HUB","urlPath":"/closedgroup/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"CommunityPage","type":"COMMUNITY","urlPath":"/","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"ForumMessagePage","type":"FORUM_TOPIC","urlPath":"/discussions/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"IdeaPostPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730142000000,"localOverride":null,"page":{"id":"CommunityHub.Page","type":"CUSTOM","urlPath":"/Directory","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"BlogMessagePage","type":"BLOG_ARTICLE","urlPath":"/blog/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"RegistrationPage","type":"USER","urlPath":"/register","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"EditGroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"ForumEditPage","type":"FORUM","urlPath":"/discussions/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"ResetPasswordPage","type":"USER","urlPath":"/resetpassword/:userId/:resetPasswordToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730142000000,"localOverride":null,"page":{"id":"AllBlogs.Page","type":"CUSTOM","urlPath":"/blogs","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"TkbMessagePage","type":"TKB_ARTICLE","urlPath":"/kb/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"BlogEditPage","type":"BLOG","urlPath":"/blog/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"ManageUsersPage","type":"USER","urlPath":"/users/manage/:tab?/:manageUsersTab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"ForumReplyPage","type":"FORUM_REPLY","urlPath":"/discussions/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"PrivacyPolicyPage","type":"COMMUNITY","urlPath":"/privacypolicy","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"NotificationPage","type":"COMMUNITY","urlPath":"/notifications","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"UserPage","type":"USER","urlPath":"/users/:login/:userId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"OccasionReplyPage","type":"OCCASION_REPLY","urlPath":"/event/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"ManageMembersPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/manage/:tab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"SearchResultsPage","type":"COMMUNITY","urlPath":"/search","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"BlogReplyPage","type":"BLOG_REPLY","urlPath":"/blog/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"GroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"TermsOfServicePage","type":"COMMUNITY","urlPath":"/termsofservice","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"CategoryPage","type":"CATEGORY","urlPath":"/category/:categoryId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"ForumViewAllTopicsPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/all-topics/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"TkbPostPage","type":"TKB","urlPath":"/category/:categoryId/kbs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429407,"localOverride":null,"page":{"id":"GroupHubPostPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"}],"localOverride":false},"CachedAsset:text:en_US-components/context/AppContext/AppContextProvider-0":{"__typename":"CachedAsset","id":"text:en_US-components/context/AppContext/AppContextProvider-0","value":{"noCommunity":"Cannot find community","noUser":"Cannot find current user","noNode":"Cannot find node with id {nodeId}","noMessage":"Cannot find message with id {messageId}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-0":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-0","value":{"title":"Loading..."},"localOverride":false},"User:user:-1":{"__typename":"User","id":"user:-1","uid":-1,"login":"Deleted","email":"","avatar":null,"rank":null,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":"ANONYMOUS","registrationTime":null,"confirmEmailStatus":false,"registrationAccessLevel":"VIEW","ssoRegistrationFields":[]},"ssoId":null,"profileSettings":{"__typename":"ProfileSettings","dateDisplayStyle":{"__typename":"InheritableStringSettingWithPossibleValues","key":"layout.friendly_dates_enabled","value":"false","localValue":"true","possibleValues":["true","false"]},"dateDisplayFormat":{"__typename":"InheritableStringSetting","key":"layout.format_pattern_date","value":"MMM dd yyyy","localValue":"MM-dd-yyyy"},"language":{"__typename":"InheritableStringSettingWithPossibleValues","key":"profile.language","value":"en-US","localValue":"en","possibleValues":["en-US"]}},"deleted":false},"Theme:customTheme1":{"__typename":"Theme","id":"customTheme1"},"Category:category:cis":{"__typename":"Category","id":"category:cis","entityType":"CATEGORY","displayId":"cis","nodeType":"category","depth":4,"title":"Core Infrastructure and Security","shortTitle":"Core Infrastructure and Security","parent":{"__ref":"Category:category:microsoft-security"}},"Category:category:top":{"__typename":"Category","id":"category:top","displayId":"top","nodeType":"category","depth":0,"title":"Top","entityType":"CATEGORY","shortTitle":"Top"},"Category:category:communities":{"__typename":"Category","id":"category:communities","displayId":"communities","nodeType":"category","depth":1,"parent":{"__ref":"Category:category:top"},"title":"Communities","entityType":"CATEGORY","shortTitle":"Communities"},"Category:category:products-services":{"__typename":"Category","id":"category:products-services","displayId":"products-services","nodeType":"category","depth":2,"parent":{"__ref":"Category:category:communities"},"title":"Products","entityType":"CATEGORY","shortTitle":"Products"},"Category:category:microsoft-security":{"__typename":"Category","id":"category:microsoft-security","displayId":"microsoft-security","nodeType":"category","depth":3,"parent":{"__ref":"Category:category:products-services"},"title":"Microsoft Security","entityType":"CATEGORY","shortTitle":"Microsoft Security","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Blog:board:CoreInfrastructureandSecurityBlog":{"__typename":"Blog","id":"board:CoreInfrastructureandSecurityBlog","entityType":"BLOG","displayId":"CoreInfrastructureandSecurityBlog","nodeType":"board","depth":5,"conversationStyle":"BLOG","title":"Core Infrastructure and Security Blog","description":"","avatar":null,"profileSettings":{"__typename":"ProfileSettings","language":null},"parent":{"__ref":"Category:category:cis"},"ancestors":{"__typename":"CoreNodeConnection","edges":[{"__typename":"CoreNodeEdge","node":{"__ref":"Community:community:gxcuf89792"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:communities"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:products-services"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:microsoft-security"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:cis"}}]},"userContext":{"__typename":"NodeUserContext","canAddAttachments":false,"canUpdateNode":false,"canPostMessages":false,"isSubscribed":false},"boardPolicies":{"__typename":"BoardPolicies","canPublishArticleOnCreate":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","args":[]}}},"shortTitle":"Core Infrastructure and Security Blog","repliesProperties":{"__typename":"RepliesProperties","sortOrder":"REVERSE_PUBLISH_TIME","repliesFormat":"threaded"},"eventPath":"category:cis/category:microsoft-security/category:products-services/category:communities/community:gxcuf89792board:CoreInfrastructureandSecurityBlog/","tagProperties":{"__typename":"TagNodeProperties","tagsEnabled":{"__typename":"PolicyResult","failureReason":null}},"requireTags":true,"tagType":"FREEFORM_ONLY"},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc","height":512,"width":512,"mimeType":"image/png"},"Rank:rank:4":{"__typename":"Rank","id":"rank:4","position":6,"name":"Microsoft","color":"333333","icon":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc\"}"},"rankStyle":"OUTLINE"},"User:user:315057":{"__typename":"User","id":"user:315057","uid":315057,"login":"NoMoePwds","deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/dS0zMTUwNTctMzc1NzU3aTY3REE5RUZEMTJBRTg3RjM"},"rank":{"__ref":"Rank:rank:4"},"email":"","messagesCount":66,"biography":null,"topicsCount":64,"kudosReceivedCount":12,"kudosGivenCount":3,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2019-04-05T11:12:44.824-07:00","confirmEmailStatus":null},"followersCount":null,"solutionsCount":0},"BlogTopicMessage:message:1128560":{"__typename":"BlogTopicMessage","uid":1128560,"subject":"Introducing Certificate Template API","id":"message:1128560","revisionNum":3,"repliesCount":1,"author":{"__ref":"User:user:315057"},"depth":0,"hasGivenKudo":false,"board":{"__ref":"Blog:board:CoreInfrastructureandSecurityBlog"},"conversation":{"__ref":"Conversation:conversation:1128560"},"messagePolicies":{"__typename":"MessagePolicies","canPublishArticleOnEdit":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","args":[]}},"canModerateSpamMessage":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","key":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","args":[]}}},"contentWorkflow":{"__typename":"ContentWorkflow","state":"PUBLISH","scheduledPublishTime":null,"scheduledTimezone":null,"userContext":{"__typename":"MessageWorkflowContext","canSubmitForReview":null,"canEdit":false,"canRecall":null,"canSubmitForPublication":null,"canReturnToAuthor":null,"canPublish":null,"canReturnToReview":null,"canSchedule":false},"shortScheduledTimezone":null},"readOnly":false,"editFrozen":false,"moderationData":{"__ref":"ModerationData:moderation_data:1128560"},"teaser":"

First published on TECHNET on Sep 25, 2009 WARNING: USE OF THE SAMPLE CODE PROVIDED IN THIS ARTICLE IS AT YOUR OWN RISK.

","body":"

First published on TECHNET on Sep 25, 2009

\n

WARNING: USE OF THE SAMPLE CODE PROVIDED IN THIS ARTICLE IS AT YOUR OWN RISK. Microsoft provides this sample code \"as is\" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.

\n

 

\n

In this post I would like to talk about how a developer can package a certificate template as a resource in their application to be later installed in a customer environment. This post assumes that you have good understanding of the Enterprise CAs, certificate templates, and Active Directory.

\n

 

\n

Here is one possible scenario. Let’s say your application uses a certificate for communication between its client and server components. You have specific requirements as to what that certificate should look like. Your application is meant to work in Windows environment so you want to take advantage of Windows CA and autoenrollment and have CA issue certificates for you clients so you don’t have to worry about the certificate enrollment yourself. But how do you configure CA and more importantly certificate template from your code? Before Windows Server 2008 R2 your only solution to those is to provide documentation for your admins on how to do it manually or go directly to AD using LDAP and modify certificate template objects (this option is a hack and not supported by the way).

\n

 

\n

In Windows Server 2008 R2 and Windows 7 we’ve added an API that will let developers to do the template setup in code in a supported way. As a developer you will actually need a Windows Server 2008 R2 installation in your test environment to create your resource, but your application can run on either Windows Server 2008 R2 or Windows 7. This will become clear as I go through the steps in this post.

\n

 

\n

First, a little historical perspective to understand why going directly to AD to modify certificate templates is not supported. Certificate templates have been around for a while and were not even customizable originally. When customization was added a lot of rules about what settings make sense were implemented in the certificate template MMC snap-in (certtmpl.msc). For example, you can only select to archive a private key on a certificate template that has encryption purpose. There are many more rules like that. These rules ensured that certificate templates are always “good” and allowed some assumptions to be made in the code that actually used the templates. Hence, we don’t want others to mess with certificate templates outside of our snap-in. However, as the number of applications that used certificates grew, we started receiving request to programmatically create certificate templates.

\n

 

\n

So how do you do it? At the very high level the process looks like this:

\n

 

\n

At the development time:

\n

 

\n

1. Setup a test MS PKI environment including a DC, CA, Certificate Enrollment Policy Service, and Certificate Enrollment Service.

\n

 

\n

2. Configure a template as desired.

\n

 

\n

3. Export a template.

\n

 

\n

4. Include exported template in your application and develop a code that will import it at the execution time.

\n

 

\n

At the setup execution time

\n

 

\n

1. Import exported template to your customer’s AD environment.

\n

 

\n

2. Configure a CA to issue a template.

\n

 

\n

Development Time

\n

 

\n

Most of the work will have to happen during development (more importantly all of the manual work).

\n

 

\n

Environment Setup

\n

 

\n

Before you can create and export a certificate template, you need to setup a proper environment. You need only one Windows Server 2008 R2 machine for that.

\n

 

\n

First of all, we need an Enterprise CA and of course a DC because templates are stored in Active Directory. Don’t worry about the names you use for you CA, DC, or domain. None of that stuff will be exported by our API.

\n

 

\n

Then you need to setup Certificate Enrollment Policy Service and Certificate Enrollment Service. These are new role services for the ADCS server role in Windows Server 2008 R2. To learn more about these role services see this page . The reason we need them is because we want to leverage the XML that they produce to export our template.

\n

 

\n

Template Configuration

\n

 

\n

Now configure a template that you application needs by duplicating one of the default templates. Don’t bother with the security settings (more on that later) except for making sure that your test user account that you are going to use during export has Read and Enroll permissions on the template. If you need more than one template, configure them as well. Our API can handle exporting/importing of multiple templates.

\n

 

\n

Once you have configured the template(s), add it for issuance on your CA and remove all other templates. This will ensure that you only export what you need.

\n

 

\n

Exporting a Template

\n

 

\n

You need to write a little code to export a template. This code doesn’t need to be included in the actual application since the application only requires the import. Here is sample code that exports templates to a file:

\n

 

\n

\n
\n
   1: //
\n\n
   2: // exports template from a policy server and saves the data
\n\n
   3: // into some file. Defaulting to a user context and kerb auth. 
\n\n
   4: //
\n\n
   5: static void Export(string policyServerURL, string fileName)
\n\n
   6: {
\n\n
   7:     //
\n\n
   8:     // Get template data from policy server
\n\n
   9:     //
\n\n
  10:     IX509EnrollmentPolicyServer policyServer = new CX509EnrollmentPolicyWebServiceClass();
\n\n
  11:     policyServer.Initialize(
\n\n
  12:         policyServerURL, 
\n\n
  13:         null, 
\n\n
  14:         X509EnrollmentAuthFlags.X509AuthKerberos, 
\n\n
  15:         false, 
\n\n
  16:         X509CertificateEnrollmentContext.ContextUser
\n\n
  17:         );
\n\n
  18:     policyServer.SetCredential(0, X509EnrollmentAuthFlags.X509AuthKerberos, null, null);
\n\n
  19:     policyServer.LoadPolicy(X509EnrollmentPolicyLoadOption.LoadOptionReload);
\n\n
  20:  
\n\n
  21:     //
\n\n
  22:     // export template data and save it to a file
\n\n
  23:     //
\n\n
  24:     byte[] exportedData = (byte[])policyServer.Export(
\n\n
  25:         X509EnrollmentPolicyExportFlags.ExportOIDs | X509EnrollmentPolicyExportFlags.ExportTemplates
\n\n
  26:         );
\n\n
  27:     using(FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
\n\n
  28:     {
\n\n
  29:         fs.Write(exportedData, 0, exportedData.Length);
\n\n
  30:     }
\n\n
  31: }
\n
\n
\n

 

\n

 

\n

 

\n

Although, the APIs are documented in the MSDN , I will add few words on the parameters and the general flow of the code here.

\n

 

\n

First we create an instance of an object that implements IX509EnrollmentPolicyServer interface and represents a Certificate Enrollment Policy Service. We initialize it with its URL that you can get from the IIS snap-in -> Default Web Site -> properties of an application that has “PolicyProvider_CEP” in its name. The AuthFlags are set based on the authentication option you chose during Certificate Enrollment Policy Service setup. I’ve used Kerberos here as this the easiest one to deal with. The Context parameter is set to ContextUser so make sure you ACL template so that the user account executing this code has access.

\n

 

\n

Then we call SetCredential() method with a X509EnrollmentAuthFlags.X509AuthKerberos type. No other parameters need to be set as this type uses Windows Integrated authentication.

\n

 

\n

After that we call LoadPolicy() which actually retrieve the Certificate Enrollment Policy Service end point. We use X509EnrollmentPolicyLoadOption.LoadOptionReload to avoid caching. More on that later.

\n

 

\n

Finally we export the template data and associated OID objects and write them to a file. Later we can package that file into our application for import at the run time.

\n

 

\n

A word of caution on caching… If you’re playing with a template by changing its properties and trying to export it, there several caches that you should be aware of. First the cache that the APIs maintain on each client. That cache can be avoided by passing X509EnrollmentPolicyLoadOption.LoadOptionReload option to the LoadPolicy() method call as I have done above. Second cache exists on the Certificate Enrollment Policy Service side. To avoid this cache go to the IIS manager snapin -> Default Web Site -> *CEP* -> Application Setting and create a RetryIntervalMs application setting and set it to something small like 1000. This makes policy service to refresh its cache every second.

\n

 

\n

Execution Time

\n

 

\n

There are several tasks that you would need to do at the setup and uninstall time.

\n

 

\n

Setup

\n

 

\n

During setup process, you want to load the exported template data and import it into your customer’s Active Directory. Here is a sample code that does that:

\n

 

\n

\n
\n
   1: //
\n\n
   2: // Read exported template data from the file
\n\n
   3: //
\n\n
   4: static void Import(string fileName)
\n\n
   5: {
\n\n
   6:     //
\n\n
   7:     // read exported template data from a file
\n\n
   8:     //
\n\n
   9:     byte[] importedData = null;
\n\n
  10:     using(FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None))
\n\n
  11:     {
\n\n
  12:         importedData = new byte[fs.Length];
\n\n
  13:         fs.Read(importedData, 0, importedData.Length);
\n\n
  14:     }
\n\n
  15:  
\n\n
  16:     //
\n\n
  17:     // Initialize policy server interface with exported data instead of connecting
\n\n
  18:     // to a real policy server
\n\n
  19:     //
\n\n
  20:     IX509EnrollmentPolicyServer importPolicyServer = new CX509EnrollmentPolicyWebServiceClass();
\n\n
  21:     importPolicyServer.InitializeImport(importedData);
\n\n
  22:     
\n\n
  23:     //
\n\n
  24:     // go through each imported template, set its security descriptor, and 
\n\n
  25:     // write it to Active Directory
\n\n
  26:     //
\n\n
  27:     IX509CertificateTemplates templates = importPolicyServer.GetTemplates();
\n\n
  28:     foreach (IX509CertificateTemplate template in templates)
\n\n
  29:     {
\n\n
  30:         IX509CertificateTemplateWritable writableTemplate = new CX509CertificateTemplateADWritableClass();
\n\n
  31:         writableTemplate.Initialize(template);
\n\n
  32:         writableTemplate.set_Property(EnrollmentTemplateProperty.TemplatePropSecurityDescriptor, SDDL);
\n\n
  33:         writableTemplate.Commit(CommitTemplateFlags.CommitFlagSaveTemplateGenerateOID, null);
\n\n
  34:     }
\n\n
  35: }
\n\n
  36:  
\n\n
  37: private const string SDDL = 
\n\n
  38:     \"O:EA\" + //owner is Enterprise Admins
\n\n
  39:     \"G:EA\" + //group is EA as well
\n\n
  40:     \"D:PAI\" + //DACL with SE_DACL_PROTECTED and SE_DACL_AUTO_INHERITED 
\n\n
  41:     \"(OA;;CR;a05b8cc2-17bc-4802-a710-e7c15ab866a2;;DU)\" + //autoenroll for Domain Users
\n\n
  42:     \"(OA;;RPWPCR;0e10c968-78fb-11d2-90d4-00c04f79dc55;;DA)\" + //enroll for Domain Admins
\n\n
  43:     \"(OA;;RPWPCR;0e10c968-78fb-11d2-90d4-00c04f79dc55;;DU)\" + //enroll for Domain Users
\n\n
  44:     \"(OA;;RPWPCR;0e10c968-78fb-11d2-90d4-00c04f79dc55;;EA)\" + //enroll for Enterprise Admins
\n\n
  45:     \"(A;;CCDCLCSWRPWPDTLOSDRCWDWO;;;DA)\" + //all access to Domain Admins
\n\n
  46:     \"(A;;CCDCLCSWRPWPDTLOSDRCWDWO;;;EA)\" + //all access to Enterprise Admins
\n\n
  47:     \"(A;;LCRPLORC;;;AU)\"; //read for Authenticated Users
\n
\n
\n

 

\n

First we read the exported data from the same file we used in the export sample.

\n

 

\n

Then we create an instance of an object that implements IX509EnrollmentPolicyServer and initialize it with data we have read from the file earlier. This time we don’t actually need to call LoadPolicy() method or set the authentication parameters since we don’t need to retrieve the data from the actual Certificate Enrollment Policy Service endpoint.

\n

 

\n

Finally, we iterate through the template collection and for each template in the collection we create an instance of the writable template object. These objects can actually we written to the Active Directory.

\n

 

\n

However, before we actually commit the write operation, we need to set the security descriptor property. This property is not exported (it doesn’t make sense to export it actually since it would be meaningless outside of the test environment we’ve used to create a template) and if you don’t set it you will inherit a default setting that would only allow enrollment for your domain admins. Note that at this time you can’t change other properties besides security descriptor.

\n

 

\n

When we call Commit() method to complete the write operation, we pass the CommitFlagSaveTemplateGenerateOID flag to tell the API to generate an OID for us similar to what the duplicate action does in the certificate template snap-in.

\n

 

\n

Note that in order for you to add a certificate template, you need write permissions to the Configuration\\Services\\Public Key Services AD container which in default setup means Enterprise Admins membership.

\n

 

\n

If you have created custom application policies (aka EKUs) in your test environment by going to the Extensions tab -> Edit -> Add… -> New…, you would need to install those in the customer environment using certutil.exe since the API at this time doesn’t support importing those. Here is how you would do it:

\n

 

\n

\n

\n

Certutil.exe -f -oid 1.2.3.4.5.6.7.8.9.0 MyEKU 1033 3

\n
\n
\n

What this command does is registers your EKU in Active Directory. We use -f switch to allow certutil.exe to create new object. Then we provide the OID value and the display name. The 1033 is the language ID that will be used by the certificate UI when it encounters this OID in a certificate. For a list of language IDs see this MSDN page . The last parameter specifies the type of OID object we are creating which is the Application Policy type.

\n
\n

 

\n

To check that registration has been successful in your code just check the return code from certutil.exe. Manually you can run this command:

\n

 

\n

\n

C:\\>certutil.exe -v -oid 1.2.3.4.5.6.7.8.9.0
System default Language Id:: 409 (1033)
1.2.3.4.5.6.7.8.9.0 – MyEKU
pwszName = MyEKU
CRYPT_ENHKEY_USAGE_OID_GROUP_ID (7)
dwValue = 0
0: 1033,TestEKU2
CertUtil: -oid command completed successfully.

\n
\n

 

\n

Once you have certificate template setup you can use ICertAadmin2::SetCAProperty() method to add your template to be issued by a CA. Here is a sample code on how to do it:

\n

 

\n

\n
\n
   1: static void AddTemplateToCA(string templateName, string templateOid)
\n\n
   2: {
\n\n
   3:     //
\n\n
   4:     // let user to pick a CA
\n\n
   5:     //
\n\n
   6:     ICertConfig2 certConfig = new CCertConfigClass();
\n\n
   7:     string caConfig = certConfig.GetConfig(0x1 /* CC_UIPICKCONFIG */);
\n\n
   8:  
\n\n
   9:     //
\n\n
  10:     // get current templates that are configured on the CA 
\n\n
  11:     //
\n\n
  12:     ICertAdmin2 admin = new CCertAdminClass();
\n\n
  13:     StringBuilder sb = new StringBuilder(
\n\n
  14:         (string)admin.GetCAProperty(caConfig, 29 /* CA_PROP_TEMPLATES */, 0, 4 /*string*/, 0)
\n\n
  15:         );
\n\n
  16:     
\n\n
  17:     //
\n\n
  18:     // add new template to the list and update the CA
\n\n
  19:     //
\n\n
  20:     sb.Append(templateName);
\n\n
  21:     sb.Append(\"\\n\");
\n\n
  22:     sb.Append(templateOid);
\n\n
  23:     sb.Append(\"\\n\");
\n\n
  24:     object newTemplates = sb.ToString();
\n\n
  25:     admin.SetCAProperty(caConfig, 29, 0, 4, ref newTemplates);
\n\n
  26: }
\n
\n
\n

 

\n

This method takes two parameters the template name and template OID. It is obvious where we get the template name (we created it at the development time), but where is the application can get the OID. You can record it right after you wrote the template to AD by calling the GetProperty() method with the EnrollmentTemplateProperty.TemplatePropOID flag.

\n

 

\n

Now let’s look at what the code does. First, we use ICertConfig::GetConfig() method to prompt a user to select a CA. Then we query for a currently configured list of templates from that CA. Finally, we modify the list by adding our template to the end of it and by setting the list back on the CA. You need to be an admin on the CA for this code to run.

\n

 

\n

Uninstall

\n

 

\n

When your application performs uninstall you need a way to delete a template and/or OIDs that you have created during setup.

\n

 

\n

The OID deletion is simple and can be achieved by this certutil.exe command:

\n

 

\n

\n

Certutil.exe -oid 1.2.3.4.5.6.7.8.9.0 delete

\n
\n

 

\n

To remove a template from a CA, you can use ICertConfig2::Next() method to iterate through all enterprise CAs and use ICertAdmin2 interface to find which CA has your template configured. Removing it from a CA is a reverse operation from what we did in the AddTemplateToCA() sample code earlier.

\n

 

\n

The deletion of a template is a little bit more involved. Here is a sample code to do it:

\n

 

\n

\n

\n

\n
\n
   1: //
\n\n
   2: // Delete a template identified by templateCommonName paramter from AD
\n\n
   3: // using a DC specified by dcDnsName parameter
\n\n
   4: //
\n\n
   5: static void Delete(string templateCommonName, string dcDnsName)
\n\n
   6: {
\n\n
   7:     //
\n\n
   8:     // Get templates from AD
\n\n
   9:     //
\n\n
  10:     IX509EnrollmentPolicyServer adPolicyServer = new CX509EnrollmentPolicyActiveDirectoryClass();
\n\n
  11:     adPolicyServer.Initialize(
\n\n
  12:         dcDnsName, 
\n\n
  13:         null, 
\n\n
  14:         X509EnrollmentAuthFlags.X509AuthKerberos, 
\n\n
  15:         false, 
\n\n
  16:         X509CertificateEnrollmentContext.ContextUser
\n\n
  17:         );
\n\n
  18:     adPolicyServer.LoadPolicy(X509EnrollmentPolicyLoadOption.LoadOptionReload);
\n\n
  19:     IX509CertificateTemplates templates = adPolicyServer.GetTemplates();
\n\n
  20:     
\n\n
  21:     //
\n\n
  22:     // go through each template and if a match found delete from AD
\n\n
  23:     //
\n\n
  24:     foreach (IX509CertificateTemplate template in templates)
\n\n
  25:     {
\n\n
  26:         string currentTemplateCommonName = 
\n\n
  27:             (string)template.get_Property(EnrollmentTemplateProperty.TemplatePropCommonName);
\n\n
  28:  
\n\n
  29:         if (0 == String.Compare(currentTemplateCommonName, templateCommonName, true))
\n\n
  30:         {
\n\n
  31:             IX509CertificateTemplateWritable writableTemplate = new CX509CertificateTemplateADWritableClass();
\n\n
  32:             writableTemplate.Initialize(template);
\n\n
  33:             writableTemplate.Commit(CommitTemplateFlags.CommitFlagDeleteTemplate, dcDnsName);
\n\n
  34:             break;
\n\n
  35:         }
\n\n
  36:     }
\n\n
  37: }
\n
\n
\n
\n
\n

 

\n

This code looks very similar to the import case. First we create IX509EnrollmentPolicyServer instance only this time we use a CX509EnrollmentPolicyActiveDirectoryClass class. Then we get all of the templates currently in AD and go through that collection until we find the one we looking for. Once we find it we delete by calling the Commit() method with the CommitFlagDeleteTemplate flag. You need to have the delete permission on the Configuration\\Services\\Public Key Services AD container (specifically Certificate Templates container and OID container) for the deletion to succeed.

\n

 

\n

In my sample I’m specifying a DC name that I want APIs to work with. This is not required. You can just pass null to get a default DC. However, it is a good general practice to use a specific DC to get consistent results. Otherwise different method invocations can actually be performed against different DCs and you may run into problems with AD data not being consistent across DCs you are using.

","body@stringLength":"70850","rawBody":"

First published on TECHNET on Sep 25, 2009

\n

WARNING: USE OF THE SAMPLE CODE PROVIDED IN THIS ARTICLE IS AT YOUR OWN RISK. Microsoft provides this sample code \"as is\" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.

\n

 

\n

In this post I would like to talk about how a developer can package a certificate template as a resource in their application to be later installed in a customer environment. This post assumes that you have good understanding of the Enterprise CAs, certificate templates, and Active Directory.

\n

 

\n

Here is one possible scenario. Let’s say your application uses a certificate for communication between its client and server components. You have specific requirements as to what that certificate should look like. Your application is meant to work in Windows environment so you want to take advantage of Windows CA and autoenrollment and have CA issue certificates for you clients so you don’t have to worry about the certificate enrollment yourself. But how do you configure CA and more importantly certificate template from your code? Before Windows Server 2008 R2 your only solution to those is to provide documentation for your admins on how to do it manually or go directly to AD using LDAP and modify certificate template objects (this option is a hack and not supported by the way).

\n

 

\n

In Windows Server 2008 R2 and Windows 7 we’ve added an API that will let developers to do the template setup in code in a supported way. As a developer you will actually need a Windows Server 2008 R2 installation in your test environment to create your resource, but your application can run on either Windows Server 2008 R2 or Windows 7. This will become clear as I go through the steps in this post.

\n

 

\n

First, a little historical perspective to understand why going directly to AD to modify certificate templates is not supported. Certificate templates have been around for a while and were not even customizable originally. When customization was added a lot of rules about what settings make sense were implemented in the certificate template MMC snap-in (certtmpl.msc). For example, you can only select to archive a private key on a certificate template that has encryption purpose. There are many more rules like that. These rules ensured that certificate templates are always “good” and allowed some assumptions to be made in the code that actually used the templates. Hence, we don’t want others to mess with certificate templates outside of our snap-in. However, as the number of applications that used certificates grew, we started receiving request to programmatically create certificate templates.

\n

 

\n

So how do you do it? At the very high level the process looks like this:

\n

 

\n

At the development time:

\n

 

\n

1. Setup a test MS PKI environment including a DC, CA, Certificate Enrollment Policy Service, and Certificate Enrollment Service.

\n

 

\n

2. Configure a template as desired.

\n

 

\n

3. Export a template.

\n

 

\n

4. Include exported template in your application and develop a code that will import it at the execution time.

\n

 

\n

At the setup execution time

\n

 

\n

1. Import exported template to your customer’s AD environment.

\n

 

\n

2. Configure a CA to issue a template.

\n

 

\n

Development Time

\n

 

\n

Most of the work will have to happen during development (more importantly all of the manual work).

\n

 

\n

Environment Setup

\n

 

\n

Before you can create and export a certificate template, you need to setup a proper environment. You need only one Windows Server 2008 R2 machine for that.

\n

 

\n

First of all, we need an Enterprise CA and of course a DC because templates are stored in Active Directory. Don’t worry about the names you use for you CA, DC, or domain. None of that stuff will be exported by our API.

\n

 

\n

Then you need to setup Certificate Enrollment Policy Service and Certificate Enrollment Service. These are new role services for the ADCS server role in Windows Server 2008 R2. To learn more about these role services see this page . The reason we need them is because we want to leverage the XML that they produce to export our template.

\n

 

\n

Template Configuration

\n

 

\n

Now configure a template that you application needs by duplicating one of the default templates. Don’t bother with the security settings (more on that later) except for making sure that your test user account that you are going to use during export has Read and Enroll permissions on the template. If you need more than one template, configure them as well. Our API can handle exporting/importing of multiple templates.

\n

 

\n

Once you have configured the template(s), add it for issuance on your CA and remove all other templates. This will ensure that you only export what you need.

\n

 

\n

Exporting a Template

\n

 

\n

You need to write a little code to export a template. This code doesn’t need to be included in the actual application since the application only requires the import. Here is sample code that exports templates to a file:

\n

 

\n

\n
\n
   1: //
\n\n
   2: // exports template from a policy server and saves the data
\n\n
   3: // into some file. Defaulting to a user context and kerb auth. 
\n\n
   4: //
\n\n
   5: static void Export(string policyServerURL, string fileName)
\n\n
   6: {
\n\n
   7:     //
\n\n
   8:     // Get template data from policy server
\n\n
   9:     //
\n\n
  10:     IX509EnrollmentPolicyServer policyServer = new CX509EnrollmentPolicyWebServiceClass();
\n\n
  11:     policyServer.Initialize(
\n\n
  12:         policyServerURL, 
\n\n
  13:         null, 
\n\n
  14:         X509EnrollmentAuthFlags.X509AuthKerberos, 
\n\n
  15:         false, 
\n\n
  16:         X509CertificateEnrollmentContext.ContextUser
\n\n
  17:         );
\n\n
  18:     policyServer.SetCredential(0, X509EnrollmentAuthFlags.X509AuthKerberos, null, null);
\n\n
  19:     policyServer.LoadPolicy(X509EnrollmentPolicyLoadOption.LoadOptionReload);
\n\n
  20:  
\n\n
  21:     //
\n\n
  22:     // export template data and save it to a file
\n\n
  23:     //
\n\n
  24:     byte[] exportedData = (byte[])policyServer.Export(
\n\n
  25:         X509EnrollmentPolicyExportFlags.ExportOIDs | X509EnrollmentPolicyExportFlags.ExportTemplates
\n\n
  26:         );
\n\n
  27:     using(FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
\n\n
  28:     {
\n\n
  29:         fs.Write(exportedData, 0, exportedData.Length);
\n\n
  30:     }
\n\n
  31: }
\n
\n
\n

 

\n

 

\n

 

\n

Although, the APIs are documented in the MSDN , I will add few words on the parameters and the general flow of the code here.

\n

 

\n

First we create an instance of an object that implements IX509EnrollmentPolicyServer interface and represents a Certificate Enrollment Policy Service. We initialize it with its URL that you can get from the IIS snap-in -> Default Web Site -> properties of an application that has “PolicyProvider_CEP” in its name. The AuthFlags are set based on the authentication option you chose during Certificate Enrollment Policy Service setup. I’ve used Kerberos here as this the easiest one to deal with. The Context parameter is set to ContextUser so make sure you ACL template so that the user account executing this code has access.

\n

 

\n

Then we call SetCredential() method with a X509EnrollmentAuthFlags.X509AuthKerberos type. No other parameters need to be set as this type uses Windows Integrated authentication.

\n

 

\n

After that we call LoadPolicy() which actually retrieve the Certificate Enrollment Policy Service end point. We use X509EnrollmentPolicyLoadOption.LoadOptionReload to avoid caching. More on that later.

\n

 

\n

Finally we export the template data and associated OID objects and write them to a file. Later we can package that file into our application for import at the run time.

\n

 

\n

A word of caution on caching… If you’re playing with a template by changing its properties and trying to export it, there several caches that you should be aware of. First the cache that the APIs maintain on each client. That cache can be avoided by passing X509EnrollmentPolicyLoadOption.LoadOptionReload option to the LoadPolicy() method call as I have done above. Second cache exists on the Certificate Enrollment Policy Service side. To avoid this cache go to the IIS manager snapin -> Default Web Site -> *CEP* -> Application Setting and create a RetryIntervalMs application setting and set it to something small like 1000. This makes policy service to refresh its cache every second.

\n

 

\n

Execution Time

\n

 

\n

There are several tasks that you would need to do at the setup and uninstall time.

\n

 

\n

Setup

\n

 

\n

During setup process, you want to load the exported template data and import it into your customer’s Active Directory. Here is a sample code that does that:

\n

 

\n

\n
\n
   1: //
\n\n
   2: // Read exported template data from the file
\n\n
   3: //
\n\n
   4: static void Import(string fileName)
\n\n
   5: {
\n\n
   6:     //
\n\n
   7:     // read exported template data from a file
\n\n
   8:     //
\n\n
   9:     byte[] importedData = null;
\n\n
  10:     using(FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None))
\n\n
  11:     {
\n\n
  12:         importedData = new byte[fs.Length];
\n\n
  13:         fs.Read(importedData, 0, importedData.Length);
\n\n
  14:     }
\n\n
  15:  
\n\n
  16:     //
\n\n
  17:     // Initialize policy server interface with exported data instead of connecting
\n\n
  18:     // to a real policy server
\n\n
  19:     //
\n\n
  20:     IX509EnrollmentPolicyServer importPolicyServer = new CX509EnrollmentPolicyWebServiceClass();
\n\n
  21:     importPolicyServer.InitializeImport(importedData);
\n\n
  22:     
\n\n
  23:     //
\n\n
  24:     // go through each imported template, set its security descriptor, and 
\n\n
  25:     // write it to Active Directory
\n\n
  26:     //
\n\n
  27:     IX509CertificateTemplates templates = importPolicyServer.GetTemplates();
\n\n
  28:     foreach (IX509CertificateTemplate template in templates)
\n\n
  29:     {
\n\n
  30:         IX509CertificateTemplateWritable writableTemplate = new CX509CertificateTemplateADWritableClass();
\n\n
  31:         writableTemplate.Initialize(template);
\n\n
  32:         writableTemplate.set_Property(EnrollmentTemplateProperty.TemplatePropSecurityDescriptor, SDDL);
\n\n
  33:         writableTemplate.Commit(CommitTemplateFlags.CommitFlagSaveTemplateGenerateOID, null);
\n\n
  34:     }
\n\n
  35: }
\n\n
  36:  
\n\n
  37: private const string SDDL = 
\n\n
  38:     \"O:EA\" + //owner is Enterprise Admins
\n\n
  39:     \"G:EA\" + //group is EA as well
\n\n
  40:     \"D:PAI\" + //DACL with SE_DACL_PROTECTED and SE_DACL_AUTO_INHERITED 
\n\n
  41:     \"(OA;;CR;a05b8cc2-17bc-4802-a710-e7c15ab866a2;;DU)\" + //autoenroll for Domain Users
\n\n
  42:     \"(OA;;RPWPCR;0e10c968-78fb-11d2-90d4-00c04f79dc55;;DA)\" + //enroll for Domain Admins
\n\n
  43:     \"(OA;;RPWPCR;0e10c968-78fb-11d2-90d4-00c04f79dc55;;DU)\" + //enroll for Domain Users
\n\n
  44:     \"(OA;;RPWPCR;0e10c968-78fb-11d2-90d4-00c04f79dc55;;EA)\" + //enroll for Enterprise Admins
\n\n
  45:     \"(A;;CCDCLCSWRPWPDTLOSDRCWDWO;;;DA)\" + //all access to Domain Admins
\n\n
  46:     \"(A;;CCDCLCSWRPWPDTLOSDRCWDWO;;;EA)\" + //all access to Enterprise Admins
\n\n
  47:     \"(A;;LCRPLORC;;;AU)\"; //read for Authenticated Users
\n
\n
\n

 

\n

First we read the exported data from the same file we used in the export sample.

\n

 

\n

Then we create an instance of an object that implements IX509EnrollmentPolicyServer and initialize it with data we have read from the file earlier. This time we don’t actually need to call LoadPolicy() method or set the authentication parameters since we don’t need to retrieve the data from the actual Certificate Enrollment Policy Service endpoint.

\n

 

\n

Finally, we iterate through the template collection and for each template in the collection we create an instance of the writable template object. These objects can actually we written to the Active Directory.

\n

 

\n

However, before we actually commit the write operation, we need to set the security descriptor property. This property is not exported (it doesn’t make sense to export it actually since it would be meaningless outside of the test environment we’ve used to create a template) and if you don’t set it you will inherit a default setting that would only allow enrollment for your domain admins. Note that at this time you can’t change other properties besides security descriptor.

\n

 

\n

When we call Commit() method to complete the write operation, we pass the CommitFlagSaveTemplateGenerateOID flag to tell the API to generate an OID for us similar to what the duplicate action does in the certificate template snap-in.

\n

 

\n

Note that in order for you to add a certificate template, you need write permissions to the Configuration\\Services\\Public Key Services AD container which in default setup means Enterprise Admins membership.

\n

 

\n

If you have created custom application policies (aka EKUs) in your test environment by going to the Extensions tab -> Edit -> Add… -> New…, you would need to install those in the customer environment using certutil.exe since the API at this time doesn’t support importing those. Here is how you would do it:

\n

 

\n

\n

\n

Certutil.exe -f -oid 1.2.3.4.5.6.7.8.9.0 MyEKU 1033 3

\n
\n
\n

What this command does is registers your EKU in Active Directory. We use -f switch to allow certutil.exe to create new object. Then we provide the OID value and the display name. The 1033 is the language ID that will be used by the certificate UI when it encounters this OID in a certificate. For a list of language IDs see this MSDN page . The last parameter specifies the type of OID object we are creating which is the Application Policy type.

\n
\n

 

\n

To check that registration has been successful in your code just check the return code from certutil.exe. Manually you can run this command:

\n

 

\n

\n

C:\\>certutil.exe -v -oid 1.2.3.4.5.6.7.8.9.0
System default Language Id:: 409 (1033)
1.2.3.4.5.6.7.8.9.0 – MyEKU
pwszName = MyEKU
CRYPT_ENHKEY_USAGE_OID_GROUP_ID (7)
dwValue = 0
0: 1033,TestEKU2
CertUtil: -oid command completed successfully.

\n
\n

 

\n

Once you have certificate template setup you can use ICertAadmin2::SetCAProperty() method to add your template to be issued by a CA. Here is a sample code on how to do it:

\n

 

\n

\n
\n
   1: static void AddTemplateToCA(string templateName, string templateOid)
\n\n
   2: {
\n\n
   3:     //
\n\n
   4:     // let user to pick a CA
\n\n
   5:     //
\n\n
   6:     ICertConfig2 certConfig = new CCertConfigClass();
\n\n
   7:     string caConfig = certConfig.GetConfig(0x1 /* CC_UIPICKCONFIG */);
\n\n
   8:  
\n\n
   9:     //
\n\n
  10:     // get current templates that are configured on the CA 
\n\n
  11:     //
\n\n
  12:     ICertAdmin2 admin = new CCertAdminClass();
\n\n
  13:     StringBuilder sb = new StringBuilder(
\n\n
  14:         (string)admin.GetCAProperty(caConfig, 29 /* CA_PROP_TEMPLATES */, 0, 4 /*string*/, 0)
\n\n
  15:         );
\n\n
  16:     
\n\n
  17:     //
\n\n
  18:     // add new template to the list and update the CA
\n\n
  19:     //
\n\n
  20:     sb.Append(templateName);
\n\n
  21:     sb.Append(\"\\n\");
\n\n
  22:     sb.Append(templateOid);
\n\n
  23:     sb.Append(\"\\n\");
\n\n
  24:     object newTemplates = sb.ToString();
\n\n
  25:     admin.SetCAProperty(caConfig, 29, 0, 4, ref newTemplates);
\n\n
  26: }
\n
\n
\n

 

\n

This method takes two parameters the template name and template OID. It is obvious where we get the template name (we created it at the development time), but where is the application can get the OID. You can record it right after you wrote the template to AD by calling the GetProperty() method with the EnrollmentTemplateProperty.TemplatePropOID flag.

\n

 

\n

Now let’s look at what the code does. First, we use ICertConfig::GetConfig() method to prompt a user to select a CA. Then we query for a currently configured list of templates from that CA. Finally, we modify the list by adding our template to the end of it and by setting the list back on the CA. You need to be an admin on the CA for this code to run.

\n

 

\n

Uninstall

\n

 

\n

When your application performs uninstall you need a way to delete a template and/or OIDs that you have created during setup.

\n

 

\n

The OID deletion is simple and can be achieved by this certutil.exe command:

\n

 

\n

\n

Certutil.exe -oid 1.2.3.4.5.6.7.8.9.0 delete

\n
\n

 

\n

To remove a template from a CA, you can use ICertConfig2::Next() method to iterate through all enterprise CAs and use ICertAdmin2 interface to find which CA has your template configured. Removing it from a CA is a reverse operation from what we did in the AddTemplateToCA() sample code earlier.

\n

 

\n

The deletion of a template is a little bit more involved. Here is a sample code to do it:

\n

 

\n

\n

\n

\n
\n
   1: //
\n\n
   2: // Delete a template identified by templateCommonName paramter from AD
\n\n
   3: // using a DC specified by dcDnsName parameter
\n\n
   4: //
\n\n
   5: static void Delete(string templateCommonName, string dcDnsName)
\n\n
   6: {
\n\n
   7:     //
\n\n
   8:     // Get templates from AD
\n\n
   9:     //
\n\n
  10:     IX509EnrollmentPolicyServer adPolicyServer = new CX509EnrollmentPolicyActiveDirectoryClass();
\n\n
  11:     adPolicyServer.Initialize(
\n\n
  12:         dcDnsName, 
\n\n
  13:         null, 
\n\n
  14:         X509EnrollmentAuthFlags.X509AuthKerberos, 
\n\n
  15:         false, 
\n\n
  16:         X509CertificateEnrollmentContext.ContextUser
\n\n
  17:         );
\n\n
  18:     adPolicyServer.LoadPolicy(X509EnrollmentPolicyLoadOption.LoadOptionReload);
\n\n
  19:     IX509CertificateTemplates templates = adPolicyServer.GetTemplates();
\n\n
  20:     
\n\n
  21:     //
\n\n
  22:     // go through each template and if a match found delete from AD
\n\n
  23:     //
\n\n
  24:     foreach (IX509CertificateTemplate template in templates)
\n\n
  25:     {
\n\n
  26:         string currentTemplateCommonName = 
\n\n
  27:             (string)template.get_Property(EnrollmentTemplateProperty.TemplatePropCommonName);
\n\n
  28:  
\n\n
  29:         if (0 == String.Compare(currentTemplateCommonName, templateCommonName, true))
\n\n
  30:         {
\n\n
  31:             IX509CertificateTemplateWritable writableTemplate = new CX509CertificateTemplateADWritableClass();
\n\n
  32:             writableTemplate.Initialize(template);
\n\n
  33:             writableTemplate.Commit(CommitTemplateFlags.CommitFlagDeleteTemplate, dcDnsName);
\n\n
  34:             break;
\n\n
  35:         }
\n\n
  36:     }
\n\n
  37: }
\n
\n
\n
\n
\n

 

\n

This code looks very similar to the import case. First we create IX509EnrollmentPolicyServer instance only this time we use a CX509EnrollmentPolicyActiveDirectoryClass class. Then we get all of the templates currently in AD and go through that collection until we find the one we looking for. Once we find it we delete by calling the Commit() method with the CommitFlagDeleteTemplate flag. You need to have the delete permission on the Configuration\\Services\\Public Key Services AD container (specifically Certificate Templates container and OID container) for the deletion to succeed.

\n

 

\n

In my sample I’m specifying a DC name that I want APIs to work with. This is not required. You can just pass null to get a default DC. However, it is a good general practice to use a specific DC to get consistent results. Otherwise different method invocations can actually be performed against different DCs and you may run into problems with AD data not being consistent across DCs you are using.

","kudosSumWeight":0,"postTime":"2020-01-24T13:48:33.759-08:00","images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"attachments":{"__typename":"AttachmentConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"tags":{"__typename":"TagConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDE","node":{"__typename":"Tag","id":"tag:PKI","text":"PKI","time":"2017-10-30T23:40:10.358-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}}]},"timeToRead":11,"rawTeaser":"

First published on TECHNET on Sep 25, 2009 WARNING: USE OF THE SAMPLE CODE PROVIDED IN THIS ARTICLE IS AT YOUR OWN RISK.

","introduction":"","coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""},"currentRevision":{"__ref":"Revision:revision:1128560_3"},"latestVersion":{"__typename":"FriendlyVersion","major":"3","minor":"0"},"metrics":{"__typename":"MessageMetrics","views":3016},"visibilityScope":"PUBLIC","canonicalUrl":null,"seoTitle":null,"seoDescription":null,"placeholder":false,"originalMessageForPlaceholder":null,"contributors":{"__typename":"UserConnection","edges":[]},"nonCoAuthorContributors":{"__typename":"UserConnection","edges":[]},"coAuthors":{"__typename":"UserConnection","edges":[]},"blogMessagePolicies":{"__typename":"BlogMessagePolicies","canDoAuthoringActionsOnBlog":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.blog.action_can_do_authoring_action.accessDenied","key":"error.lithium.policies.blog.action_can_do_authoring_action.accessDenied","args":[]}}},"archivalData":null,"replies":{"__typename":"MessageConnection","edges":[{"__typename":"MessageEdge","cursor":"MjUuMXwyLjF8aXwxMHwxMzI6MHxpbnQsMzY5MzA0MywzNjkzMDQz","node":{"__ref":"BlogReplyMessage:message:3693043"}}],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"customFields":[],"revisions({\"constraints\":{\"isPublished\":{\"eq\":true}},\"first\":1})":{"__typename":"RevisionConnection","totalCount":3}},"Conversation:conversation:1128560":{"__typename":"Conversation","id":"conversation:1128560","solved":false,"topic":{"__ref":"BlogTopicMessage:message:1128560"},"lastPostingActivityTime":"2022-12-08T13:39:01.965-08:00","lastPostTime":"2022-12-08T13:39:01.965-08:00","unreadReplyCount":1,"isSubscribed":false},"ModerationData:moderation_data:1128560":{"__typename":"ModerationData","id":"moderation_data:1128560","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"Revision:revision:1128560_3":{"__typename":"Revision","id":"revision:1128560_3","lastEditTime":"2020-02-21T06:28:45.559-08:00"},"CachedAsset:theme:customTheme1-1744326567512":{"__typename":"CachedAsset","id":"theme:customTheme1-1744326567512","value":{"id":"customTheme1","animation":{"fast":"150ms","normal":"250ms","slow":"500ms","slowest":"750ms","function":"cubic-bezier(0.07, 0.91, 0.51, 1)","__typename":"AnimationThemeSettings"},"avatar":{"borderRadius":"50%","collections":["default"],"__typename":"AvatarThemeSettings"},"basics":{"browserIcon":{"imageAssetName":"favicon-1730836283320.png","imageLastModified":"1730836286415","__typename":"ThemeAsset"},"customerLogo":{"imageAssetName":"favicon-1730836271365.png","imageLastModified":"1730836274203","__typename":"ThemeAsset"},"maximumWidthOfPageContent":"1300px","oneColumnNarrowWidth":"800px","gridGutterWidthMd":"30px","gridGutterWidthXs":"10px","pageWidthStyle":"WIDTH_OF_BROWSER","__typename":"BasicsThemeSettings"},"buttons":{"borderRadiusSm":"3px","borderRadius":"3px","borderRadiusLg":"5px","paddingY":"5px","paddingYLg":"7px","paddingYHero":"var(--lia-bs-btn-padding-y-lg)","paddingX":"12px","paddingXLg":"16px","paddingXHero":"60px","fontStyle":"NORMAL","fontWeight":"700","textTransform":"NONE","disabledOpacity":0.5,"primaryTextColor":"var(--lia-bs-white)","primaryTextHoverColor":"var(--lia-bs-white)","primaryTextActiveColor":"var(--lia-bs-white)","primaryBgColor":"var(--lia-bs-primary)","primaryBgHoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.85))","primaryBgActiveColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.7))","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","primaryBorderActive":"1px solid transparent","primaryBorderFocus":"1px solid var(--lia-bs-white)","primaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","secondaryTextColor":"var(--lia-bs-gray-900)","secondaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","secondaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","secondaryBgColor":"var(--lia-bs-gray-200)","secondaryBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","secondaryBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","secondaryBorder":"1px solid transparent","secondaryBorderHover":"1px solid transparent","secondaryBorderActive":"1px solid transparent","secondaryBorderFocus":"1px solid transparent","secondaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","tertiaryTextColor":"var(--lia-bs-gray-900)","tertiaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","tertiaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","tertiaryBgColor":"transparent","tertiaryBgHoverColor":"transparent","tertiaryBgActiveColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.04)","tertiaryBorder":"1px solid transparent","tertiaryBorderHover":"1px solid hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","tertiaryBorderActive":"1px solid transparent","tertiaryBorderFocus":"1px solid transparent","tertiaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","destructiveTextColor":"var(--lia-bs-danger)","destructiveTextHoverColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.95))","destructiveTextActiveColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.9))","destructiveBgColor":"var(--lia-bs-gray-200)","destructiveBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","destructiveBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","destructiveBorder":"1px solid transparent","destructiveBorderHover":"1px solid transparent","destructiveBorderActive":"1px solid transparent","destructiveBorderFocus":"1px solid transparent","destructiveBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","__typename":"ButtonsThemeSettings"},"border":{"color":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","mainContent":"NONE","sideContent":"LIGHT","radiusSm":"3px","radius":"5px","radiusLg":"9px","radius50":"100vw","__typename":"BorderThemeSettings"},"boxShadow":{"xs":"0 0 0 1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08), 0 3px 0 -1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.16)","sm":"0 2px 4px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.12)","md":"0 5px 15px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","lg":"0 10px 30px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","__typename":"BoxShadowThemeSettings"},"cards":{"bgColor":"var(--lia-panel-bg-color)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":"var(--lia-box-shadow-xs)","__typename":"CardsThemeSettings"},"chip":{"maxWidth":"300px","height":"30px","__typename":"ChipThemeSettings"},"coreTypes":{"defaultMessageLinkColor":"var(--lia-bs-link-color)","defaultMessageLinkDecoration":"none","defaultMessageLinkFontStyle":"NORMAL","defaultMessageLinkFontWeight":"400","defaultMessageFontStyle":"NORMAL","defaultMessageFontWeight":"400","forumColor":"#4099E2","forumFontFamily":"var(--lia-bs-font-family-base)","forumFontWeight":"var(--lia-default-message-font-weight)","forumLineHeight":"var(--lia-bs-line-height-base)","forumFontStyle":"var(--lia-default-message-font-style)","forumMessageLinkColor":"var(--lia-default-message-link-color)","forumMessageLinkDecoration":"var(--lia-default-message-link-decoration)","forumMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","forumMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","forumSolvedColor":"#148563","blogColor":"#1CBAA0","blogFontFamily":"var(--lia-bs-font-family-base)","blogFontWeight":"var(--lia-default-message-font-weight)","blogLineHeight":"1.75","blogFontStyle":"var(--lia-default-message-font-style)","blogMessageLinkColor":"var(--lia-default-message-link-color)","blogMessageLinkDecoration":"var(--lia-default-message-link-decoration)","blogMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","blogMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","tkbColor":"#4C6B90","tkbFontFamily":"var(--lia-bs-font-family-base)","tkbFontWeight":"var(--lia-default-message-font-weight)","tkbLineHeight":"1.75","tkbFontStyle":"var(--lia-default-message-font-style)","tkbMessageLinkColor":"var(--lia-default-message-link-color)","tkbMessageLinkDecoration":"var(--lia-default-message-link-decoration)","tkbMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","tkbMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaColor":"#4099E2","qandaFontFamily":"var(--lia-bs-font-family-base)","qandaFontWeight":"var(--lia-default-message-font-weight)","qandaLineHeight":"var(--lia-bs-line-height-base)","qandaFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkColor":"var(--lia-default-message-link-color)","qandaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","qandaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaSolvedColor":"#3FA023","ideaColor":"#FF8000","ideaFontFamily":"var(--lia-bs-font-family-base)","ideaFontWeight":"var(--lia-default-message-font-weight)","ideaLineHeight":"var(--lia-bs-line-height-base)","ideaFontStyle":"var(--lia-default-message-font-style)","ideaMessageLinkColor":"var(--lia-default-message-link-color)","ideaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","ideaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","ideaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","contestColor":"#FCC845","contestFontFamily":"var(--lia-bs-font-family-base)","contestFontWeight":"var(--lia-default-message-font-weight)","contestLineHeight":"var(--lia-bs-line-height-base)","contestFontStyle":"var(--lia-default-message-link-font-style)","contestMessageLinkColor":"var(--lia-default-message-link-color)","contestMessageLinkDecoration":"var(--lia-default-message-link-decoration)","contestMessageLinkFontStyle":"ITALIC","contestMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","occasionColor":"#D13A1F","occasionFontFamily":"var(--lia-bs-font-family-base)","occasionFontWeight":"var(--lia-default-message-font-weight)","occasionLineHeight":"var(--lia-bs-line-height-base)","occasionFontStyle":"var(--lia-default-message-font-style)","occasionMessageLinkColor":"var(--lia-default-message-link-color)","occasionMessageLinkDecoration":"var(--lia-default-message-link-decoration)","occasionMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","occasionMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","grouphubColor":"#333333","categoryColor":"#949494","communityColor":"#FFFFFF","productColor":"#949494","__typename":"CoreTypesThemeSettings"},"colors":{"black":"#000000","white":"#FFFFFF","gray100":"#F7F7F7","gray200":"#F7F7F7","gray300":"#E8E8E8","gray400":"#D9D9D9","gray500":"#CCCCCC","gray600":"#717171","gray700":"#707070","gray800":"#545454","gray900":"#333333","dark":"#545454","light":"#F7F7F7","primary":"#0069D4","secondary":"#333333","bodyText":"#1E1E1E","bodyBg":"#FFFFFF","info":"#409AE2","success":"#41C5AE","warning":"#FCC844","danger":"#BC341B","alertSystem":"#FF6600","textMuted":"#707070","highlight":"#FFFCAD","outline":"var(--lia-bs-primary)","custom":["#D3F5A4","#243A5E"],"__typename":"ColorsThemeSettings"},"divider":{"size":"3px","marginLeft":"4px","marginRight":"4px","borderRadius":"50%","bgColor":"var(--lia-bs-gray-600)","bgColorActive":"var(--lia-bs-gray-600)","__typename":"DividerThemeSettings"},"dropdown":{"fontSize":"var(--lia-bs-font-size-sm)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius-sm)","dividerBg":"var(--lia-bs-gray-300)","itemPaddingY":"5px","itemPaddingX":"20px","headerColor":"var(--lia-bs-gray-700)","__typename":"DropdownThemeSettings"},"email":{"link":{"color":"#0069D4","hoverColor":"#0061c2","decoration":"none","hoverDecoration":"underline","__typename":"EmailLinkSettings"},"border":{"color":"#e4e4e4","__typename":"EmailBorderSettings"},"buttons":{"borderRadiusLg":"5px","paddingXLg":"16px","paddingYLg":"7px","fontWeight":"700","primaryTextColor":"#ffffff","primaryTextHoverColor":"#ffffff","primaryBgColor":"#0069D4","primaryBgHoverColor":"#005cb8","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","__typename":"EmailButtonsSettings"},"panel":{"borderRadius":"5px","borderColor":"#e4e4e4","__typename":"EmailPanelSettings"},"__typename":"EmailThemeSettings"},"emoji":{"skinToneDefault":"#ffcd43","skinToneLight":"#fae3c5","skinToneMediumLight":"#e2cfa5","skinToneMedium":"#daa478","skinToneMediumDark":"#a78058","skinToneDark":"#5e4d43","__typename":"EmojiThemeSettings"},"heading":{"color":"var(--lia-bs-body-color)","fontFamily":"Segoe UI","fontStyle":"NORMAL","fontWeight":"400","h1FontSize":"34px","h2FontSize":"32px","h3FontSize":"28px","h4FontSize":"24px","h5FontSize":"20px","h6FontSize":"16px","lineHeight":"1.3","subHeaderFontSize":"11px","subHeaderFontWeight":"500","h1LetterSpacing":"normal","h2LetterSpacing":"normal","h3LetterSpacing":"normal","h4LetterSpacing":"normal","h5LetterSpacing":"normal","h6LetterSpacing":"normal","subHeaderLetterSpacing":"2px","h1FontWeight":"var(--lia-bs-headings-font-weight)","h2FontWeight":"var(--lia-bs-headings-font-weight)","h3FontWeight":"var(--lia-bs-headings-font-weight)","h4FontWeight":"var(--lia-bs-headings-font-weight)","h5FontWeight":"var(--lia-bs-headings-font-weight)","h6FontWeight":"var(--lia-bs-headings-font-weight)","__typename":"HeadingThemeSettings"},"icons":{"size10":"10px","size12":"12px","size14":"14px","size16":"16px","size20":"20px","size24":"24px","size30":"30px","size40":"40px","size50":"50px","size60":"60px","size80":"80px","size120":"120px","size160":"160px","__typename":"IconsThemeSettings"},"imagePreview":{"bgColor":"var(--lia-bs-gray-900)","titleColor":"var(--lia-bs-white)","controlColor":"var(--lia-bs-white)","controlBgColor":"var(--lia-bs-gray-800)","__typename":"ImagePreviewThemeSettings"},"input":{"borderColor":"var(--lia-bs-gray-600)","disabledColor":"var(--lia-bs-gray-600)","focusBorderColor":"var(--lia-bs-primary)","labelMarginBottom":"10px","btnFontSize":"var(--lia-bs-font-size-sm)","focusBoxShadow":"0 0 0 3px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","checkLabelMarginBottom":"2px","checkboxBorderRadius":"3px","borderRadiusSm":"var(--lia-bs-border-radius-sm)","borderRadius":"var(--lia-bs-border-radius)","borderRadiusLg":"var(--lia-bs-border-radius-lg)","formTextMarginTop":"4px","textAreaBorderRadius":"var(--lia-bs-border-radius)","activeFillColor":"var(--lia-bs-primary)","__typename":"InputThemeSettings"},"loading":{"dotDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.2)","dotLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.5)","barDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.06)","barLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.4)","__typename":"LoadingThemeSettings"},"link":{"color":"var(--lia-bs-primary)","hoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) - 10%))","decoration":"none","hoverDecoration":"underline","__typename":"LinkThemeSettings"},"listGroup":{"itemPaddingY":"15px","itemPaddingX":"15px","borderColor":"var(--lia-bs-gray-300)","__typename":"ListGroupThemeSettings"},"modal":{"contentTextColor":"var(--lia-bs-body-color)","contentBg":"var(--lia-bs-white)","backgroundBg":"var(--lia-bs-black)","smSize":"440px","mdSize":"760px","lgSize":"1080px","backdropOpacity":0.3,"contentBoxShadowXs":"var(--lia-bs-box-shadow-sm)","contentBoxShadow":"var(--lia-bs-box-shadow)","headerFontWeight":"700","__typename":"ModalThemeSettings"},"navbar":{"position":"FIXED","background":{"attachment":null,"clip":null,"color":"var(--lia-bs-white)","imageAssetName":"","imageLastModified":"0","origin":null,"position":"CENTER_CENTER","repeat":"NO_REPEAT","size":"COVER","__typename":"BackgroundProps"},"backgroundOpacity":0.8,"paddingTop":"15px","paddingBottom":"15px","borderBottom":"1px solid var(--lia-bs-border-color)","boxShadow":"var(--lia-bs-box-shadow-sm)","brandMarginRight":"30px","brandMarginRightSm":"10px","brandLogoHeight":"30px","linkGap":"10px","linkJustifyContent":"flex-start","linkPaddingY":"5px","linkPaddingX":"10px","linkDropdownPaddingY":"9px","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkColor":"var(--lia-bs-body-color)","linkHoverColor":"var(--lia-bs-primary)","linkFontSize":"var(--lia-bs-font-size-sm)","linkFontStyle":"NORMAL","linkFontWeight":"400","linkTextTransform":"NONE","linkLetterSpacing":"normal","linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkBgColor":"transparent","linkBgHoverColor":"transparent","linkBorder":"none","linkBorderHover":"none","linkBoxShadow":"none","linkBoxShadowHover":"none","linkTextBorderBottom":"none","linkTextBorderBottomHover":"none","dropdownPaddingTop":"10px","dropdownPaddingBottom":"15px","dropdownPaddingX":"10px","dropdownMenuOffset":"2px","dropdownDividerMarginTop":"10px","dropdownDividerMarginBottom":"10px","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","controllerIconColor":"var(--lia-bs-body-color)","controllerIconHoverColor":"var(--lia-bs-body-color)","controllerTextColor":"var(--lia-nav-controller-icon-color)","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","controllerHighlightColor":"hsla(30, 100%, 50%)","controllerHighlightTextColor":"var(--lia-yiq-light)","controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerColor":"var(--lia-nav-controller-icon-color)","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","hamburgerBgColor":"transparent","hamburgerBgHoverColor":"transparent","hamburgerBorder":"none","hamburgerBorderHover":"none","collapseMenuMarginLeft":"20px","collapseMenuDividerBg":"var(--lia-nav-link-color)","collapseMenuDividerOpacity":0.16,"__typename":"NavbarThemeSettings"},"pager":{"textColor":"var(--lia-bs-link-color)","textFontWeight":"var(--lia-font-weight-md)","textFontSize":"var(--lia-bs-font-size-sm)","__typename":"PagerThemeSettings"},"panel":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-bs-border-radius)","borderColor":"var(--lia-bs-border-color)","boxShadow":"none","__typename":"PanelThemeSettings"},"popover":{"arrowHeight":"8px","arrowWidth":"16px","maxWidth":"300px","minWidth":"100px","headerBg":"var(--lia-bs-white)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius)","boxShadow":"0 0.5rem 1rem hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.15)","__typename":"PopoverThemeSettings"},"prism":{"color":"#000000","bgColor":"#f5f2f0","fontFamily":"var(--font-family-monospace)","fontSize":"var(--lia-bs-font-size-base)","fontWeightBold":"var(--lia-bs-font-weight-bold)","fontStyleItalic":"italic","tabSize":2,"highlightColor":"#b3d4fc","commentColor":"#62707e","punctuationColor":"#6f6f6f","namespaceOpacity":"0.7","propColor":"#990055","selectorColor":"#517a00","operatorColor":"#906736","operatorBgColor":"hsla(0, 0%, 100%, 0.5)","keywordColor":"#0076a9","functionColor":"#d3284b","variableColor":"#c14700","__typename":"PrismThemeSettings"},"rte":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":" var(--lia-panel-box-shadow)","customColor1":"#bfedd2","customColor2":"#fbeeb8","customColor3":"#f8cac6","customColor4":"#eccafa","customColor5":"#c2e0f4","customColor6":"#2dc26b","customColor7":"#f1c40f","customColor8":"#e03e2d","customColor9":"#b96ad9","customColor10":"#3598db","customColor11":"#169179","customColor12":"#e67e23","customColor13":"#ba372a","customColor14":"#843fa1","customColor15":"#236fa1","customColor16":"#ecf0f1","customColor17":"#ced4d9","customColor18":"#95a5a6","customColor19":"#7e8c8d","customColor20":"#34495e","customColor21":"#000000","customColor22":"#ffffff","defaultMessageHeaderMarginTop":"40px","defaultMessageHeaderMarginBottom":"20px","defaultMessageItemMarginTop":"0","defaultMessageItemMarginBottom":"10px","diffAddedColor":"hsla(170, 53%, 51%, 0.4)","diffChangedColor":"hsla(43, 97%, 63%, 0.4)","diffNoneColor":"hsla(0, 0%, 80%, 0.4)","diffRemovedColor":"hsla(9, 74%, 47%, 0.4)","specialMessageHeaderMarginTop":"40px","specialMessageHeaderMarginBottom":"20px","specialMessageItemMarginTop":"0","specialMessageItemMarginBottom":"10px","__typename":"RteThemeSettings"},"tags":{"bgColor":"var(--lia-bs-gray-200)","bgHoverColor":"var(--lia-bs-gray-400)","borderRadius":"var(--lia-bs-border-radius-sm)","color":"var(--lia-bs-body-color)","hoverColor":"var(--lia-bs-body-color)","fontWeight":"var(--lia-font-weight-md)","fontSize":"var(--lia-font-size-xxs)","textTransform":"UPPERCASE","letterSpacing":"0.5px","__typename":"TagsThemeSettings"},"toasts":{"borderRadius":"var(--lia-bs-border-radius)","paddingX":"12px","__typename":"ToastsThemeSettings"},"typography":{"fontFamilyBase":"Segoe UI","fontStyleBase":"NORMAL","fontWeightBase":"400","fontWeightLight":"300","fontWeightNormal":"400","fontWeightMd":"500","fontWeightBold":"700","letterSpacingSm":"normal","letterSpacingXs":"normal","lineHeightBase":"1.5","fontSizeBase":"16px","fontSizeXxs":"11px","fontSizeXs":"12px","fontSizeSm":"14px","fontSizeLg":"20px","fontSizeXl":"24px","smallFontSize":"14px","customFonts":[{"source":"SERVER","name":"Segoe UI","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"},{"style":"NORMAL","weight":"300","__typename":"FontStyleData"},{"style":"NORMAL","weight":"600","__typename":"FontStyleData"},{"style":"NORMAL","weight":"700","__typename":"FontStyleData"},{"style":"ITALIC","weight":"400","__typename":"FontStyleData"}],"assetNames":["SegoeUI-normal-400.woff2","SegoeUI-normal-300.woff2","SegoeUI-normal-600.woff2","SegoeUI-normal-700.woff2","SegoeUI-italic-400.woff2"],"__typename":"CustomFont"},{"source":"SERVER","name":"MWF Fluent Icons","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"}],"assetNames":["MWFFluentIcons-normal-400.woff2"],"__typename":"CustomFont"}],"__typename":"TypographyThemeSettings"},"unstyledListItem":{"marginBottomSm":"5px","marginBottomMd":"10px","marginBottomLg":"15px","marginBottomXl":"20px","marginBottomXxl":"25px","__typename":"UnstyledListItemThemeSettings"},"yiq":{"light":"#ffffff","dark":"#000000","__typename":"YiqThemeSettings"},"colorLightness":{"primaryDark":0.36,"primaryLight":0.74,"primaryLighter":0.89,"primaryLightest":0.95,"infoDark":0.39,"infoLight":0.72,"infoLighter":0.85,"infoLightest":0.93,"successDark":0.24,"successLight":0.62,"successLighter":0.8,"successLightest":0.91,"warningDark":0.39,"warningLight":0.68,"warningLighter":0.84,"warningLightest":0.93,"dangerDark":0.41,"dangerLight":0.72,"dangerLighter":0.89,"dangerLightest":0.95,"__typename":"ColorLightnessThemeSettings"},"localOverride":false,"__typename":"Theme"},"localOverride":false},"CachedAsset:text:en_US-components/common/EmailVerification-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/common/EmailVerification-1745505309806","value":{"email.verification.title":"Email Verification Required","email.verification.message.update.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. To change your email, visit My Settings.","email.verification.message.resend.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. Resend email."},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-1745505309806","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:quilt:o365.prod:pages/blogs/BlogMessagePage:board:CoreInfrastructureandSecurityBlog-1745502713089":{"__typename":"CachedAsset","id":"quilt:o365.prod:pages/blogs/BlogMessagePage:board:CoreInfrastructureandSecurityBlog-1745502713089","value":{"id":"BlogMessagePage","container":{"id":"Common","headerProps":{"backgroundImageProps":null,"backgroundColor":null,"addComponents":null,"removeComponents":["community.widget.bannerWidget"],"componentOrder":null,"__typename":"QuiltContainerSectionProps"},"headerComponentProps":{"community.widget.breadcrumbWidget":{"disableLastCrumbForDesktop":false}},"footerProps":null,"footerComponentProps":null,"items":[{"id":"blog-article","layout":"ONE_COLUMN","bgColor":null,"showTitle":null,"showDescription":null,"textPosition":null,"textColor":null,"sectionEditLevel":"LOCKED","bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"OneColumnQuiltSection","columnMap":{"main":[{"id":"blogs.widget.blogArticleWidget","className":"lia-blog-container","props":null,"__typename":"QuiltComponent"}],"__typename":"OneSectionColumns"}},{"id":"section-1729184836777","layout":"MAIN_SIDE","bgColor":"transparent","showTitle":false,"showDescription":false,"textPosition":"CENTER","textColor":"var(--lia-bs-body-color)","sectionEditLevel":null,"bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"MainSideQuiltSection","columnMap":{"main":[],"side":[],"__typename":"MainSideSectionColumns"}}],"__typename":"QuiltContainer"},"__typename":"Quilt","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-pages/blogs/BlogMessagePage-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-pages/blogs/BlogMessagePage-1745505309806","value":{"title":"{contextMessageSubject} | {communityTitle}","errorMissing":"This blog post cannot be found","name":"Blog Message Page","section.blog-article.title":"Blog Post","archivedMessageTitle":"This Content Has Been Archived","section.section-1729184836777.title":"","section.section-1729184836777.description":"","section.CncIde.title":"Blog Post","section.tifEmD.description":"","section.tifEmD.title":""},"localOverride":false},"CachedAsset:quiltWrapper:o365.prod:Common:1745505311005":{"__typename":"CachedAsset","id":"quiltWrapper:o365.prod:Common:1745505311005","value":{"id":"Common","header":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"community.widget.navbarWidget","props":{"showUserName":true,"showRegisterLink":true,"useIconLanguagePicker":true,"useLabelLanguagePicker":true,"className":"QuiltComponent_lia-component-edit-mode__0nCcm","links":{"sideLinks":[],"mainLinks":[{"children":[],"linkType":"INTERNAL","id":"gxcuf89792","params":{},"routeName":"CommunityPage"},{"children":[],"linkType":"EXTERNAL","id":"external-link","url":"/Directory","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft365","params":{"categoryId":"microsoft365"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows","params":{"categoryId":"Windows"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"Common-microsoft365-copilot-link","params":{"categoryId":"Microsoft365Copilot"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-teams","params":{"categoryId":"MicrosoftTeams"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-securityand-compliance","params":{"categoryId":"microsoft-security"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"azure","params":{"categoryId":"Azure"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"Common-content_management-link","params":{"categoryId":"Content_Management"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"exchange","params":{"categoryId":"Exchange"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows-server","params":{"categoryId":"Windows-Server"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"outlook","params":{"categoryId":"Outlook"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-endpoint-manager","params":{"categoryId":"microsoftintune"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-2","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities","url":"/","target":"BLANK"},{"children":[{"linkType":"INTERNAL","id":"a-i","params":{"categoryId":"AI"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"education-sector","params":{"categoryId":"EducationSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"partner-community","params":{"categoryId":"PartnerCommunity"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"i-t-ops-talk","params":{"categoryId":"ITOpsTalk"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"healthcare-and-life-sciences","params":{"categoryId":"HealthcareAndLifeSciences"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-mechanics","params":{"categoryId":"MicrosoftMechanics"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"public-sector","params":{"categoryId":"PublicSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"s-m-b","params":{"categoryId":"MicrosoftforNonprofits"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"io-t","params":{"categoryId":"IoT"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"startupsat-microsoft","params":{"categoryId":"StartupsatMicrosoft"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"driving-adoption","params":{"categoryId":"DrivingAdoption"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-1","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities-1","url":"/","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external","url":"/Blogs","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external-1","url":"/Events","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft-learn-1","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-learn-blog","params":{"boardId":"MicrosoftLearnBlog","categoryId":"MicrosoftLearn"},"routeName":"BlogBoardPage"},{"linkType":"EXTERNAL","id":"external-10","url":"https://learningroomdirectory.microsoft.com/","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-3","url":"https://docs.microsoft.com/learn/dynamics365/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-4","url":"https://docs.microsoft.com/learn/m365/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-5","url":"https://docs.microsoft.com/learn/topics/sci/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-6","url":"https://docs.microsoft.com/learn/powerplatform/?wt.mc_id=techcom_header-webpage-powerplatform","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-7","url":"https://docs.microsoft.com/learn/github/?wt.mc_id=techcom_header-webpage-github","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-8","url":"https://docs.microsoft.com/learn/teams/?wt.mc_id=techcom_header-webpage-teams","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-9","url":"https://docs.microsoft.com/learn/dotnet/?wt.mc_id=techcom_header-webpage-dotnet","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-2","url":"https://docs.microsoft.com/learn/azure/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"}],"linkType":"INTERNAL","id":"microsoft-learn","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"children":[],"linkType":"INTERNAL","id":"community-info-center","params":{"categoryId":"Community-Info-Center"},"routeName":"CategoryPage"}]},"style":{"boxShadow":"var(--lia-bs-box-shadow-sm)","controllerHighlightColor":"hsla(30, 100%, 50%)","linkFontWeight":"400","dropdownDividerMarginBottom":"10px","hamburgerBorderHover":"none","linkBoxShadowHover":"none","linkFontSize":"14px","backgroundOpacity":0.8,"controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerBgColor":"transparent","hamburgerColor":"var(--lia-nav-controller-icon-color)","linkTextBorderBottom":"none","brandLogoHeight":"30px","linkBgHoverColor":"transparent","linkLetterSpacing":"normal","collapseMenuDividerOpacity":0.16,"dropdownPaddingBottom":"15px","paddingBottom":"15px","dropdownMenuOffset":"2px","hamburgerBgHoverColor":"transparent","borderBottom":"1px solid var(--lia-bs-border-color)","hamburgerBorder":"none","dropdownPaddingX":"10px","brandMarginRightSm":"10px","linkBoxShadow":"none","collapseMenuDividerBg":"var(--lia-nav-link-color)","linkColor":"var(--lia-bs-body-color)","linkJustifyContent":"flex-start","dropdownPaddingTop":"10px","controllerHighlightTextColor":"var(--lia-yiq-dark)","controllerTextColor":"var(--lia-nav-controller-icon-color)","background":{"imageAssetName":"","color":"var(--lia-bs-white)","size":"COVER","repeat":"NO_REPEAT","position":"CENTER_CENTER","imageLastModified":""},"linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkHoverColor":"var(--lia-bs-body-color)","position":"FIXED","linkBorder":"none","linkTextBorderBottomHover":"2px solid var(--lia-bs-body-color)","brandMarginRight":"30px","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","linkBorderHover":"none","collapseMenuMarginLeft":"20px","linkFontStyle":"NORMAL","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","linkPaddingX":"10px","linkPaddingY":"5px","paddingTop":"15px","linkTextTransform":"NONE","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","linkBgColor":"transparent","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkDropdownPaddingY":"9px","controllerIconColor":"var(--lia-bs-body-color)","dropdownDividerMarginTop":"10px","linkGap":"10px","controllerIconHoverColor":"var(--lia-bs-body-color)"},"showSearchIcon":false,"languagePickerStyle":"iconAndLabel"},"__typename":"QuiltComponent"},{"id":"community.widget.breadcrumbWidget","props":{"backgroundColor":"transparent","linkHighlightColor":"var(--lia-bs-primary)","visualEffects":{"showBottomBorder":true},"linkTextColor":"var(--lia-bs-gray-700)"},"__typename":"QuiltComponent"},{"id":"custom.widget.community_banner","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"usePageWidth":false,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.HeroBanner","props":{"widgetVisibility":"signedInOrAnonymous","usePageWidth":false,"useTitle":true,"cMax_items":3,"useBackground":false,"title":"","lazyLoad":false,"widgetChooser":"custom.widget.HeroBanner"},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"footer":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"custom.widget.MicrosoftFooter","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"__typename":"QuiltWrapper","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/ActionFeedback-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/common/ActionFeedback-1745505309806","value":{"joinedGroupHub.title":"Welcome","joinedGroupHub.message":"You are now a member of this group and are subscribed to updates.","groupHubInviteNotFound.title":"Invitation Not Found","groupHubInviteNotFound.message":"Sorry, we could not find your invitation to the group. The owner may have canceled the invite.","groupHubNotFound.title":"Group Not Found","groupHubNotFound.message":"The grouphub you tried to join does not exist. It may have been deleted.","existingGroupHubMember.title":"Already Joined","existingGroupHubMember.message":"You are already a member of this group.","accountLocked.title":"Account Locked","accountLocked.message":"Your account has been locked due to multiple failed attempts. Try again in {lockoutTime} minutes.","editedGroupHub.title":"Changes Saved","editedGroupHub.message":"Your group has been updated.","leftGroupHub.title":"Goodbye","leftGroupHub.message":"You are no longer a member of this group and will not receive future updates.","deletedGroupHub.title":"Deleted","deletedGroupHub.message":"The group has been deleted.","groupHubCreated.title":"Group Created","groupHubCreated.message":"{groupHubName} is ready to use","accountClosed.title":"Account Closed","accountClosed.message":"The account has been closed and you will now be redirected to the homepage","resetTokenExpired.title":"Reset Password Link has Expired","resetTokenExpired.message":"Try resetting your password again","invalidUrl.title":"Invalid URL","invalidUrl.message":"The URL you're using is not recognized. Verify your URL and try again.","accountClosedForUser.title":"Account Closed","accountClosedForUser.message":"{userName}'s account is closed","inviteTokenInvalid.title":"Invitation Invalid","inviteTokenInvalid.message":"Your invitation to the community has been canceled or expired.","inviteTokenError.title":"Invitation Verification Failed","inviteTokenError.message":"The url you are utilizing is not recognized. Verify your URL and try again","pageNotFound.title":"Access Denied","pageNotFound.message":"You do not have access to this area of the community or it doesn't exist","eventAttending.title":"Responded as Attending","eventAttending.message":"You'll be notified when there's new activity and reminded as the event approaches","eventInterested.title":"Responded as Interested","eventInterested.message":"You'll be notified when there's new activity and reminded as the event approaches","eventNotFound.title":"Event Not Found","eventNotFound.message":"The event you tried to respond to does not exist.","redirectToRelatedPage.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.message":"The content you are trying to access is archived","redirectToRelatedPage.message":"The content you are trying to access is archived","relatedUrl.archivalLink.flyoutMessage":"The content you are trying to access is archived View Archived Content"},"localOverride":false},"CachedAsset:component:custom.widget.community_banner-en-1744400827837":{"__typename":"CachedAsset","id":"component:custom.widget.community_banner-en-1744400827837","value":{"component":{"id":"custom.widget.community_banner","template":{"id":"community_banner","markupLanguage":"HANDLEBARS","style":".community-banner {\n a.top-bar.btn {\n top: 0px;\n width: 100%;\n z-index: 999;\n text-align: center;\n left: 0px;\n background: #0068b8;\n color: white;\n padding: 10px 0px;\n display: block;\n box-shadow: none !important;\n border: none !important;\n border-radius: none !important;\n margin: 0px !important;\n font-size: 14px;\n }\n}\n","texts":null,"defaults":{"config":{"applicablePages":[],"description":"community announcement text","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.community_banner","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"community announcement text","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_community_banner_community-banner_1x9u2_1 {\n a.custom_widget_community_banner_top-bar_1x9u2_2.custom_widget_community_banner_btn_1x9u2_2 {\n top: 0;\n width: 100%;\n z-index: 999;\n text-align: center;\n left: 0;\n background: #0068b8;\n color: white;\n padding: 0.625rem 0;\n display: block;\n box-shadow: none !important;\n border: none !important;\n border-radius: none !important;\n margin: 0 !important;\n font-size: 0.875rem;\n }\n}\n","tokens":{"community-banner":"custom_widget_community_banner_community-banner_1x9u2_1","top-bar":"custom_widget_community_banner_top-bar_1x9u2_2","btn":"custom_widget_community_banner_btn_1x9u2_2"}},"form":null},"localOverride":false},"CachedAsset:component:custom.widget.HeroBanner-en-1744400827837":{"__typename":"CachedAsset","id":"component:custom.widget.HeroBanner-en-1744400827837","value":{"component":{"id":"custom.widget.HeroBanner","template":{"id":"HeroBanner","markupLanguage":"REACT","style":null,"texts":{"searchPlaceholderText":"Search this community","followActionText":"Follow","unfollowActionText":"Following","searchOnHoverText":"Please enter your search term(s) and then press return key to complete a search.","blogs.sidebar.pagetitle":"Latest Blogs | Microsoft Tech Community","followThisNode":"Follow this node","unfollowThisNode":"Unfollow this node"},"defaults":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.HeroBanner","form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"__typename":"Component","localOverride":false},"globalCss":null,"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"}},"localOverride":false},"CachedAsset:component:custom.widget.MicrosoftFooter-en-1744400827837":{"__typename":"CachedAsset","id":"component:custom.widget.MicrosoftFooter-en-1744400827837","value":{"component":{"id":"custom.widget.MicrosoftFooter","template":{"id":"MicrosoftFooter","markupLanguage":"HANDLEBARS","style":".context-uhf {\n min-width: 280px;\n font-size: 15px;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.c-uhff-link {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.c-uhff {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.c-uhff-nav {\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n .c-heading-4 {\n color: #616161;\n word-break: break-word;\n font-size: 15px;\n line-height: 20px;\n padding: 36px 0 4px;\n font-weight: 600;\n }\n .c-uhff-nav-row {\n .c-uhff-nav-group {\n display: block;\n float: left;\n min-height: 1px;\n vertical-align: text-top;\n padding: 0 12px;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.c-list.f-bare {\n font-size: 11px;\n line-height: 16px;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 8px 0;\n margin: 0;\n }\n }\n }\n }\n}\n.c-uhff-base {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 30px 5% 16px;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.c-uhff-ccpa {\n font-size: 11px;\n line-height: 16px;\n float: left;\n margin: 3px 0;\n }\n a.c-uhff-ccpa:hover {\n text-decoration: underline;\n }\n ul.c-list {\n font-size: 11px;\n line-height: 16px;\n float: right;\n margin: 3px 0;\n color: #616161;\n li {\n padding: 0 24px 4px 0;\n display: inline-block;\n }\n }\n .c-list.f-bare {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 30px 24px 16px;\n }\n}\n\n.social-share {\n position: fixed;\n top: 60%;\n transform: translateY(-50%);\n left: 0;\n z-index: 1000;\n}\n\n.sharing-options {\n list-style: none;\n padding: 0;\n margin: 0;\n display: block;\n flex-direction: column;\n background-color: white;\n width: 43px;\n border-radius: 0px 7px 7px 0px;\n}\n.linkedin-icon {\n border-top-right-radius: 7px;\n}\n.linkedin-icon:hover {\n border-radius: 0;\n}\n.social-share-rss-image {\n border-bottom-right-radius: 7px;\n}\n.social-share-rss-image:hover {\n border-radius: 0;\n}\n\n.social-link-footer {\n position: relative;\n display: block;\n margin: -2px 0;\n transition: all 0.2s ease;\n}\n.social-link-footer:hover .linkedin-icon {\n border-radius: 0;\n}\n.social-link-footer:hover .social-share-rss-image {\n border-radius: 0;\n}\n\n.social-link-footer img {\n width: 40px;\n height: auto;\n transition: filter 0.3s ease;\n}\n\n.social-share-list {\n width: 40px;\n}\n.social-share-rss-image {\n width: 40px;\n}\n\n.share-icon {\n border: 2px solid transparent;\n display: inline-block;\n position: relative;\n}\n\n.share-icon:hover {\n opacity: 1;\n border: 2px solid white;\n box-sizing: border-box;\n}\n\n.share-icon:hover .label {\n opacity: 1;\n visibility: visible;\n border: 2px solid white;\n box-sizing: border-box;\n border-left: none;\n}\n\n.label {\n position: absolute;\n left: 100%;\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: all 0.2s ease;\n color: white;\n border-radius: 0 10 0 10px;\n top: 50%;\n transform: translateY(-50%);\n height: 40px;\n border-radius: 0 6px 6px 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px 5px 20px 8px;\n margin-left: -1px;\n}\n.linkedin {\n background-color: #0474b4;\n}\n.facebook {\n background-color: #3c5c9c;\n}\n.twitter {\n background-color: white;\n color: black;\n}\n.reddit {\n background-color: #fc4404;\n}\n.mail {\n background-color: #848484;\n}\n.bluesky {\n background-color: white;\n color: black;\n}\n.rss {\n background-color: #ec7b1c;\n}\n#RSS {\n width: 40px;\n height: 40px;\n}\n\n@media (max-width: 991px) {\n .social-share {\n display: none;\n }\n}\n","texts":{"New tab":"What's New","New 1":"Surface Laptop Studio 2","New 2":"Surface Laptop Go 3","New 3":"Surface Pro 9","New 4":"Surface Laptop 5","New 5":"Surface Studio 2+","New 6":"Copilot in Windows","New 7":"Microsoft 365","New 8":"Windows 11 apps","Store tab":"Microsoft Store","Store 1":"Account Profile","Store 2":"Download Center","Store 3":"Microsoft Store Support","Store 4":"Returns","Store 5":"Order tracking","Store 6":"Certified Refurbished","Store 7":"Microsoft Store Promise","Store 8":"Flexible Payments","Education tab":"Education","Edu 1":"Microsoft in education","Edu 2":"Devices for education","Edu 3":"Microsoft Teams for Education","Edu 4":"Microsoft 365 Education","Edu 5":"How to buy for your school","Edu 6":"Educator Training and development","Edu 7":"Deals for students and parents","Edu 8":"Azure for students","Business tab":"Business","Bus 1":"Microsoft Cloud","Bus 2":"Microsoft Security","Bus 3":"Dynamics 365","Bus 4":"Microsoft 365","Bus 5":"Microsoft Power Platform","Bus 6":"Microsoft Teams","Bus 7":"Microsoft Industry","Bus 8":"Small Business","Developer tab":"Developer & IT","Dev 1":"Azure","Dev 2":"Developer Center","Dev 3":"Documentation","Dev 4":"Microsoft Learn","Dev 5":"Microsoft Tech Community","Dev 6":"Azure Marketplace","Dev 7":"AppSource","Dev 8":"Visual Studio","Company tab":"Company","Com 1":"Careers","Com 2":"About Microsoft","Com 3":"Company News","Com 4":"Privacy at Microsoft","Com 5":"Investors","Com 6":"Diversity and inclusion","Com 7":"Accessiblity","Com 8":"Sustainibility"},"defaults":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.MicrosoftFooter","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_MicrosoftFooter_context-uhf_105bp_1 {\n min-width: 17.5rem;\n font-size: 0.9375rem;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-link_105bp_12 {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff_105bp_12 {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.custom_widget_MicrosoftFooter_c-uhff-nav_105bp_35 {\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n .custom_widget_MicrosoftFooter_c-heading-4_105bp_49 {\n color: #616161;\n word-break: break-word;\n font-size: 0.9375rem;\n line-height: 1.25rem;\n padding: 2.25rem 0 0.25rem;\n font-weight: 600;\n }\n .custom_widget_MicrosoftFooter_c-uhff-nav-row_105bp_57 {\n .custom_widget_MicrosoftFooter_c-uhff-nav-group_105bp_58 {\n display: block;\n float: left;\n min-height: 0.0625rem;\n vertical-align: text-top;\n padding: 0 0.75rem;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.custom_widget_MicrosoftFooter_c-list_105bp_78.custom_widget_MicrosoftFooter_f-bare_105bp_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 0.5rem 0;\n margin: 0;\n }\n }\n }\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff-base_105bp_94 {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 1.875rem 5% 1rem;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: left;\n margin: 0.1875rem 0;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107:hover {\n text-decoration: underline;\n }\n ul.custom_widget_MicrosoftFooter_c-list_105bp_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: right;\n margin: 0.1875rem 0;\n color: #616161;\n li {\n padding: 0 1.5rem 0.25rem 0;\n display: inline-block;\n }\n }\n .custom_widget_MicrosoftFooter_c-list_105bp_78.custom_widget_MicrosoftFooter_f-bare_105bp_78 {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 1.875rem 1.5rem 1rem;\n }\n}\n.custom_widget_MicrosoftFooter_social-share_105bp_138 {\n position: fixed;\n top: 60%;\n transform: translateY(-50%);\n left: 0;\n z-index: 1000;\n}\n.custom_widget_MicrosoftFooter_sharing-options_105bp_146 {\n list-style: none;\n padding: 0;\n margin: 0;\n display: block;\n flex-direction: column;\n background-color: white;\n width: 2.6875rem;\n border-radius: 0 0.4375rem 0.4375rem 0;\n}\n.custom_widget_MicrosoftFooter_linkedin-icon_105bp_156 {\n border-top-right-radius: 7px;\n}\n.custom_widget_MicrosoftFooter_linkedin-icon_105bp_156:hover {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n border-bottom-right-radius: 7px;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162:hover {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169 {\n position: relative;\n display: block;\n margin: -0.125rem 0;\n transition: all 0.2s ease;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169:hover .custom_widget_MicrosoftFooter_linkedin-icon_105bp_156 {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169:hover .custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169 img {\n width: 2.5rem;\n height: auto;\n transition: filter 0.3s ease;\n}\n.custom_widget_MicrosoftFooter_social-share-list_105bp_188 {\n width: 2.5rem;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n width: 2.5rem;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195 {\n border: 2px solid transparent;\n display: inline-block;\n position: relative;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195:hover {\n opacity: 1;\n border: 2px solid white;\n box-sizing: border-box;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195:hover .custom_widget_MicrosoftFooter_label_105bp_207 {\n opacity: 1;\n visibility: visible;\n border: 2px solid white;\n box-sizing: border-box;\n border-left: none;\n}\n.custom_widget_MicrosoftFooter_label_105bp_207 {\n position: absolute;\n left: 100%;\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: all 0.2s ease;\n color: white;\n border-radius: 0 10 0 0.625rem;\n top: 50%;\n transform: translateY(-50%);\n height: 2.5rem;\n border-radius: 0 0.375rem 0.375rem 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1.25rem 0.3125rem 1.25rem 0.5rem;\n margin-left: -0.0625rem;\n}\n.custom_widget_MicrosoftFooter_linkedin_105bp_156 {\n background-color: #0474b4;\n}\n.custom_widget_MicrosoftFooter_facebook_105bp_237 {\n background-color: #3c5c9c;\n}\n.custom_widget_MicrosoftFooter_twitter_105bp_240 {\n background-color: white;\n color: black;\n}\n.custom_widget_MicrosoftFooter_reddit_105bp_244 {\n background-color: #fc4404;\n}\n.custom_widget_MicrosoftFooter_mail_105bp_247 {\n background-color: #848484;\n}\n.custom_widget_MicrosoftFooter_bluesky_105bp_250 {\n background-color: white;\n color: black;\n}\n.custom_widget_MicrosoftFooter_rss_105bp_254 {\n background-color: #ec7b1c;\n}\n#custom_widget_MicrosoftFooter_RSS_105bp_1 {\n width: 2.5rem;\n height: 2.5rem;\n}\n@media (max-width: 991px) {\n .custom_widget_MicrosoftFooter_social-share_105bp_138 {\n display: none;\n }\n}\n","tokens":{"context-uhf":"custom_widget_MicrosoftFooter_context-uhf_105bp_1","c-uhff-link":"custom_widget_MicrosoftFooter_c-uhff-link_105bp_12","c-uhff":"custom_widget_MicrosoftFooter_c-uhff_105bp_12","c-uhff-nav":"custom_widget_MicrosoftFooter_c-uhff-nav_105bp_35","c-heading-4":"custom_widget_MicrosoftFooter_c-heading-4_105bp_49","c-uhff-nav-row":"custom_widget_MicrosoftFooter_c-uhff-nav-row_105bp_57","c-uhff-nav-group":"custom_widget_MicrosoftFooter_c-uhff-nav-group_105bp_58","c-list":"custom_widget_MicrosoftFooter_c-list_105bp_78","f-bare":"custom_widget_MicrosoftFooter_f-bare_105bp_78","c-uhff-base":"custom_widget_MicrosoftFooter_c-uhff-base_105bp_94","c-uhff-ccpa":"custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107","social-share":"custom_widget_MicrosoftFooter_social-share_105bp_138","sharing-options":"custom_widget_MicrosoftFooter_sharing-options_105bp_146","linkedin-icon":"custom_widget_MicrosoftFooter_linkedin-icon_105bp_156","social-share-rss-image":"custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162","social-link-footer":"custom_widget_MicrosoftFooter_social-link-footer_105bp_169","social-share-list":"custom_widget_MicrosoftFooter_social-share-list_105bp_188","share-icon":"custom_widget_MicrosoftFooter_share-icon_105bp_195","label":"custom_widget_MicrosoftFooter_label_105bp_207","linkedin":"custom_widget_MicrosoftFooter_linkedin_105bp_156","facebook":"custom_widget_MicrosoftFooter_facebook_105bp_237","twitter":"custom_widget_MicrosoftFooter_twitter_105bp_240","reddit":"custom_widget_MicrosoftFooter_reddit_105bp_244","mail":"custom_widget_MicrosoftFooter_mail_105bp_247","bluesky":"custom_widget_MicrosoftFooter_bluesky_105bp_250","rss":"custom_widget_MicrosoftFooter_rss_105bp_254","RSS":"custom_widget_MicrosoftFooter_RSS_105bp_1"}},"form":null},"localOverride":false},"CachedAsset:text:en_US-components/community/Breadcrumb-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/community/Breadcrumb-1745505309806","value":{"navLabel":"Breadcrumbs","dropdown":"Additional parent page navigation"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBanner-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBanner-1745505309806","value":{"messageMarkedAsSpam":"This post has been marked as spam","messageMarkedAsSpam@board:TKB":"This article has been marked as spam","messageMarkedAsSpam@board:BLOG":"This post has been marked as spam","messageMarkedAsSpam@board:FORUM":"This discussion has been marked as spam","messageMarkedAsSpam@board:OCCASION":"This event has been marked as spam","messageMarkedAsSpam@board:IDEA":"This idea has been marked as spam","manageSpam":"Manage Spam","messageMarkedAsAbuse":"This post has been marked as abuse","messageMarkedAsAbuse@board:TKB":"This article has been marked as abuse","messageMarkedAsAbuse@board:BLOG":"This post has been marked as abuse","messageMarkedAsAbuse@board:FORUM":"This discussion has been marked as abuse","messageMarkedAsAbuse@board:OCCASION":"This event has been marked as abuse","messageMarkedAsAbuse@board:IDEA":"This idea has been marked as abuse","preModCommentAuthorText":"This comment will be published as soon as it is approved","preModCommentModeratorText":"This comment is awaiting moderation","messageMarkedAsOther":"This post has been rejected due to other reasons","messageMarkedAsOther@board:TKB":"This article has been rejected due to other reasons","messageMarkedAsOther@board:BLOG":"This post has been rejected due to other reasons","messageMarkedAsOther@board:FORUM":"This discussion has been rejected due to other reasons","messageMarkedAsOther@board:OCCASION":"This event has been rejected due to other reasons","messageMarkedAsOther@board:IDEA":"This idea has been rejected due to other reasons","messageArchived":"This post was archived on {date}","relatedUrl":"View Related Content","relatedContentText":"Showing related content","archivedContentLink":"View Archived Content"},"localOverride":false},"Category:category:Exchange":{"__typename":"Category","id":"category:Exchange","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Outlook":{"__typename":"Category","id":"category:Outlook","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Community-Info-Center":{"__typename":"Category","id":"category:Community-Info-Center","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:EducationSector":{"__typename":"Category","id":"category:EducationSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:DrivingAdoption":{"__typename":"Category","id":"category:DrivingAdoption","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Azure":{"__typename":"Category","id":"category:Azure","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows-Server":{"__typename":"Category","id":"category:Windows-Server","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftTeams":{"__typename":"Category","id":"category:MicrosoftTeams","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PublicSector":{"__typename":"Category","id":"category:PublicSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoft365":{"__typename":"Category","id":"category:microsoft365","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:IoT":{"__typename":"Category","id":"category:IoT","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:HealthcareAndLifeSciences":{"__typename":"Category","id":"category:HealthcareAndLifeSciences","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:ITOpsTalk":{"__typename":"Category","id":"category:ITOpsTalk","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftLearn":{"__typename":"Category","id":"category:MicrosoftLearn","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Blog:board:MicrosoftLearnBlog":{"__typename":"Blog","id":"board:MicrosoftLearnBlog","blogPolicies":{"__typename":"BlogPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:AI":{"__typename":"Category","id":"category:AI","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftMechanics":{"__typename":"Category","id":"category:MicrosoftMechanics","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftforNonprofits":{"__typename":"Category","id":"category:MicrosoftforNonprofits","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:StartupsatMicrosoft":{"__typename":"Category","id":"category:StartupsatMicrosoft","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PartnerCommunity":{"__typename":"Category","id":"category:PartnerCommunity","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Microsoft365Copilot":{"__typename":"Category","id":"category:Microsoft365Copilot","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows":{"__typename":"Category","id":"category:Windows","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Content_Management":{"__typename":"Category","id":"category:Content_Management","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoftintune":{"__typename":"Category","id":"category:microsoftintune","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"QueryVariables:TopicReplyList:message:1128560:3":{"__typename":"QueryVariables","id":"TopicReplyList:message:1128560:3","value":{"id":"message:1128560","first":10,"sorts":{"postTime":{"direction":"DESC"}},"repliesFirst":3,"repliesFirstDepthThree":1,"repliesSorts":{"postTime":{"direction":"DESC"}},"useAvatar":true,"useAuthorLogin":true,"useAuthorRank":true,"useBody":true,"useKudosCount":true,"useTimeToRead":false,"useMedia":false,"useReadOnlyIcon":false,"useRepliesCount":true,"useSearchSnippet":false,"useAcceptedSolutionButton":false,"useSolvedBadge":false,"useAttachments":false,"attachmentsFirst":5,"useTags":true,"useNodeAncestors":false,"useUserHoverCard":false,"useNodeHoverCard":false,"useModerationStatus":true,"usePreviewSubjectModal":false,"useMessageStatus":true}},"ROOT_MUTATION":{"__typename":"Mutation"},"CachedAsset:text:en_US-components/community/Navbar-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/community/Navbar-1745505309806","value":{"community":"Community Home","inbox":"Inbox","manageContent":"Manage Content","tos":"Terms of Service","forgotPassword":"Forgot Password","themeEditor":"Theme Editor","edit":"Edit Navigation Bar","skipContent":"Skip to content","gxcuf89792":"Tech Community","external-1":"Events","s-m-b":"Nonprofit Community","windows-server":"Windows Server","education-sector":"Education Sector","driving-adoption":"Driving Adoption","Common-content_management-link":"Content Management","microsoft-learn":"Microsoft Learn","s-q-l-server":"Content Management","partner-community":"Microsoft Partner Community","microsoft365":"Microsoft 365","external-9":".NET","external-8":"Teams","external-7":"Github","products-services":"Products","external-6":"Power Platform","communities-1":"Topics","external-5":"Microsoft Security","planner":"Outlook","external-4":"Microsoft 365","external-3":"Dynamics 365","azure":"Azure","healthcare-and-life-sciences":"Healthcare and Life Sciences","external-2":"Azure","microsoft-mechanics":"Microsoft Mechanics","microsoft-learn-1":"Community","external-10":"Learning Room Directory","microsoft-learn-blog":"Blog","windows":"Windows","i-t-ops-talk":"ITOps Talk","external-link-1":"View All","microsoft-securityand-compliance":"Microsoft Security","public-sector":"Public Sector","community-info-center":"Lounge","external-link-2":"View All","microsoft-teams":"Microsoft Teams","external":"Blogs","microsoft-endpoint-manager":"Microsoft Intune","startupsat-microsoft":"Startups at Microsoft","exchange":"Exchange","a-i":"AI and Machine Learning","io-t":"Internet of Things (IoT)","Common-microsoft365-copilot-link":"Microsoft 365 Copilot","outlook":"Microsoft 365 Copilot","external-link":"Community Hubs","communities":"Products"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarHamburgerDropdown-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarHamburgerDropdown-1745505309806","value":{"hamburgerLabel":"Side Menu"},"localOverride":false},"CachedAsset:text:en_US-components/community/BrandLogo-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/community/BrandLogo-1745505309806","value":{"logoAlt":"Khoros","themeLogoAlt":"Brand Logo"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarTextLinks-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarTextLinks-1745505309806","value":{"more":"More"},"localOverride":false},"CachedAsset:text:en_US-components/authentication/AuthenticationLink-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/authentication/AuthenticationLink-1745505309806","value":{"title.login":"Sign In","title.registration":"Register","title.forgotPassword":"Forgot Password","title.multiAuthLogin":"Sign In"},"localOverride":false},"CachedAsset:text:en_US-components/nodes/NodeLink-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/nodes/NodeLink-1745505309806","value":{"place":"Place {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageView/MessageViewStandard-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageView/MessageViewStandard-1745505309806","value":{"anonymous":"Anonymous","author":"{messageAuthorLogin}","authorBy":"{messageAuthorLogin}","board":"{messageBoardTitle}","replyToUser":" to {parentAuthor}","showMoreReplies":"Show More","replyText":"Reply","repliesText":"Replies","markedAsSolved":"Marked as Solved","movedMessagePlaceholder.BLOG":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.TKB":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.FORUM":"{count, plural, =0 {This reply has been} other {These replies have been} }","movedMessagePlaceholder.IDEA":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.OCCASION":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholderUrlText":"moved.","messageStatus":"Status: ","statusChanged":"Status changed: {previousStatus} to {currentStatus}","statusAdded":"Status added: {status}","statusRemoved":"Status removed: {status}","labelExpand":"expand replies","labelCollapse":"collapse replies","unhelpfulReason.reason1":"Content is outdated","unhelpfulReason.reason2":"Article is missing information","unhelpfulReason.reason3":"Content is for a different Product","unhelpfulReason.reason4":"Doesn't match what I was searching for"},"localOverride":false},"CachedAsset:text:en_US-components/messages/ThreadedReplyList-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/messages/ThreadedReplyList-1745505309806","value":{"title":"{count, plural, one{# Reply} other{# Replies}}","title@board:BLOG":"{count, plural, one{# Comment} other{# Comments}}","title@board:TKB":"{count, plural, one{# Comment} other{# Comments}}","title@board:IDEA":"{count, plural, one{# Comment} other{# Comments}}","title@board:OCCASION":"{count, plural, one{# Comment} other{# Comments}}","noRepliesTitle":"No Replies","noRepliesTitle@board:BLOG":"No Comments","noRepliesTitle@board:TKB":"No Comments","noRepliesTitle@board:IDEA":"No Comments","noRepliesTitle@board:OCCASION":"No Comments","noRepliesDescription":"Be the first to reply","noRepliesDescription@board:BLOG":"Be the first to comment","noRepliesDescription@board:TKB":"Be the first to comment","noRepliesDescription@board:IDEA":"Be the first to comment","noRepliesDescription@board:OCCASION":"Be the first to comment","messageReadOnlyAlert:BLOG":"Comments have been turned off for this post","messageReadOnlyAlert:TKB":"Comments have been turned off for this article","messageReadOnlyAlert:IDEA":"Comments have been turned off for this idea","messageReadOnlyAlert:FORUM":"Replies have been turned off for this discussion","messageReadOnlyAlert:OCCASION":"Comments have been turned off for this event"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyCallToAction-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyCallToAction-1745505309806","value":{"leaveReply":"Leave a reply...","leaveReply@board:BLOG@message:root":"Leave a comment...","leaveReply@board:TKB@message:root":"Leave a comment...","leaveReply@board:IDEA@message:root":"Leave a comment...","leaveReply@board:OCCASION@message:root":"Leave a comment...","repliesTurnedOff.FORUM":"Replies are turned off for this topic","repliesTurnedOff.BLOG":"Comments are turned off for this topic","repliesTurnedOff.TKB":"Comments are turned off for this topic","repliesTurnedOff.IDEA":"Comments are turned off for this topic","repliesTurnedOff.OCCASION":"Comments are turned off for this topic","infoText":"Stop poking me!"},"localOverride":false},"Rank:rank:37":{"__typename":"Rank","id":"rank:37","position":18,"name":"Copper Contributor","color":"333333","icon":null,"rankStyle":"TEXT"},"User:user:1645222":{"__typename":"User","id":"user:1645222","uid":1645222,"login":"Sundance","biography":null,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2022-12-08T13:19:17.639-08:00"},"deleted":false,"email":"","avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/m_assets/avatars/default/avatar-11.svg?time=0"},"rank":{"__ref":"Rank:rank:37"},"entityType":"USER","eventPath":"community:gxcuf89792/user:1645222"},"ModerationData:moderation_data:3693043":{"__typename":"ModerationData","id":"moderation_data:3693043","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"BlogReplyMessage:message:3693043":{"__typename":"BlogReplyMessage","author":{"__ref":"User:user:1645222"},"id":"message:3693043","revisionNum":1,"uid":3693043,"depth":1,"hasGivenKudo":false,"subscribed":false,"board":{"__ref":"Blog:board:CoreInfrastructureandSecurityBlog"},"parent":{"__ref":"BlogTopicMessage:message:1128560"},"conversation":{"__ref":"Conversation:conversation:1128560"},"subject":"Re: Introducing Certificate Template API","moderationData":{"__ref":"ModerationData:moderation_data:3693043"},"body":"

This is truly useful. But I am having a problem with the export function.  For one thing, I am not sure what to pass in as the policyServerURL.  At the moment,  I am using the fully qualified name of my domain controller, which happens to also be the Certification Authority. Is it correct?  Still on the Export call ((byte[])policyServer.Export etc...) I get a NOT IMPLEMENTED (80004001)exception.  Any idea what I am doing wrong? I am running on a Server 2016 machine. Enterprise CA.  I don't have issues running the other functions.

 

","body@stripHtml({\"removeProcessingText\":false,\"removeSpoilerMarkup\":false,\"removeTocMarkup\":false,\"truncateLength\":200})@stringLength":"218","kudosSumWeight":0,"repliesCount":0,"postTime":"2022-12-08T13:39:01.965-08:00","lastPublishTime":"2022-12-08T13:39:01.965-08:00","metrics":{"__typename":"MessageMetrics","views":744},"visibilityScope":"PUBLIC","placeholder":false,"originalMessageForPlaceholder":null,"entityType":"BLOG_REPLY","eventPath":"category:cis/category:microsoft-security/category:products-services/category:communities/community:gxcuf89792board:CoreInfrastructureandSecurityBlog/message:1128560/message:3693043","replies":{"__typename":"MessageConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"customFields":[],"attachments":{"__typename":"AttachmentConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarDropdownToggle-1745505309806","value":{"ariaLabelClosed":"Press the down arrow to open the menu"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/QueryHandler-1745505309806","value":{"title":"Query Handler"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCoverImage-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCoverImage-1745505309806","value":{"coverImageTitle":"Cover Image"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeTitle-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeTitle-1745505309806","value":{"nodeTitle":"{nodeTitle, select, community {Community} other {{nodeTitle}}} "},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTimeToRead-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTimeToRead-1745505309806","value":{"minReadText":"{min} MIN READ"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageSubject-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageSubject-1745505309806","value":{"noSubject":"(no subject)"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserLink-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserLink-1745505309806","value":{"authorName":"View Profile: {author}","anonymous":"Anonymous"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserRank-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserRank-1745505309806","value":{"rankName":"{rankName}","userRank":"Author rank {rankName}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTime-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTime-1745505309806","value":{"postTime":"Published: {time}","lastPublishTime":"Last Update: {time}","conversation.lastPostingActivityTime":"Last posting activity time: {time}","conversation.lastPostTime":"Last post time: {time}","moderationData.rejectTime":"Rejected time: {time}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBody-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBody-1745505309806","value":{"showMessageBody":"Show More","mentionsErrorTitle":"{mentionsType, select, board {Board} user {User} message {Message} other {}} No Longer Available","mentionsErrorMessage":"The {mentionsType} you are trying to view has been removed from the community.","videoProcessing":"Video is being processed. Please try again in a few minutes.","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCustomFields-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCustomFields-1745505309806","value":{"CustomField.default.label":"Value of {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageRevision-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageRevision-1745505309806","value":{"lastUpdatedDatePublished":"{publishCount, plural, one{Published} other{Updated}} {date}","lastUpdatedDateDraft":"Created {date}","version":"Version {major}.{minor}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyButton-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyButton-1745505309806","value":{"repliesCount":"{count}","title":"Reply","title@board:BLOG@message:root":"Comment","title@board:TKB@message:root":"Comment","title@board:IDEA@message:root":"Comment","title@board:OCCASION@message:root":"Comment"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageAuthorBio-1745505309806","value":{"sendMessage":"Send Message","actionMessage":"Follow this blog board to get notified when there's new activity","coAuthor":"CO-PUBLISHER","contributor":"CONTRIBUTOR","userProfile":"View Profile","iconlink":"Go to {name} {type}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserAvatar-1745505309806","value":{"altText":"{login}'s avatar","altTextGeneric":"User's avatar"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/ranks/UserRankLabel-1745505309806","value":{"altTitle":"Icon for {rankName} rank"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserRegistrationDate-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserRegistrationDate-1745505309806","value":{"noPrefix":"{date}","withPrefix":"Joined {date}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeAvatar-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeAvatar-1745505309806","value":{"altTitle":"Node avatar for {nodeTitle}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeDescription-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeDescription-1745505309806","value":{"description":"{description}"},"localOverride":false},"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-components/tags/TagView/TagViewChip-1745505309806","value":{"tagLabelName":"Tag name {tagName}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1745505309806":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeIcon-1745505309806","value":{"contentType":"Content Type {style, select, FORUM {Forum} BLOG {Blog} TKB {Knowledge Base} IDEA {Ideas} OCCASION {Events} other {}} icon"},"localOverride":false}}}},"page":"/blogs/BlogMessagePage/BlogMessagePage","query":{"boardId":"coreinfrastructureandsecurityblog","messageSubject":"introducing-certificate-template-api","messageId":"1128560"},"buildId":"HEhyUrv5OXNBIbfCLaOrw","runtimeConfig":{"buildInformationVisible":false,"logLevelApp":"info","logLevelMetrics":"info","openTelemetryClientEnabled":false,"openTelemetryConfigName":"o365","openTelemetryServiceVersion":"25.1.0","openTelemetryUniverse":"prod","openTelemetryCollector":"http://localhost:4318","openTelemetryRouteChangeAllowedTime":"5000","apolloDevToolsEnabled":false,"inboxMuteWipFeatureEnabled":false},"isFallback":false,"isExperimentalCompile":false,"dynamicIds":["./components/community/Navbar/NavbarWidget.tsx","./components/community/Breadcrumb/BreadcrumbWidget.tsx","./components/customComponent/CustomComponent/CustomComponent.tsx","./components/blogs/BlogArticleWidget/BlogArticleWidget.tsx","./components/external/components/ExternalComponent.tsx","./components/messages/MessageView/MessageViewStandard/MessageViewStandard.tsx","./components/messages/ThreadedReplyList/ThreadedReplyList.tsx","../shared/client/components/common/List/UnstyledList/UnstyledList.tsx","./components/messages/MessageView/MessageView.tsx","../shared/client/components/common/List/UnwrappedList/UnwrappedList.tsx","./components/tags/TagView/TagView.tsx","./components/tags/TagView/TagViewChip/TagViewChip.tsx"],"appGip":true,"scriptLoader":[{"id":"analytics","src":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/pagescripts/1730819800000/analytics.js?page.id=BlogMessagePage&entity.id=board%3Acoreinfrastructureandsecurityblog&entity.id=message%3A1128560","strategy":"afterInteractive"}]}