@@ -6,7 +6,7 @@ ms.topic: how-to
6
6
---
7
7
# How to create Guest Configuration policies for Windows
8
8
9
- Before creating custom policies , it's a good idea to read the conceptual overview information at the
9
+ Before creating custom policy definitions , it's a good idea to read the conceptual overview information at the
10
10
page [ Azure Policy Guest Configuration] ( ../concepts/guest-configuration.md ) .
11
11
12
12
To learn about creating Guest Configuration policies for Linux, see the page
@@ -33,9 +33,15 @@ non-Azure machine.
33
33
34
34
## Install the PowerShell module
35
35
36
- Creating a Guest Configuration artifact, automated testing of the artifact, creating a policy
37
- definition, and publishing the policy, is entirely automatable using the Guest Configuration module
38
- in PowerShell. The module can be installed on a machine running Windows, macOS, or Linux with
36
+ The Guest Configuration module automates the process of creating custom content
37
+ including:
38
+
39
+ - Creating a Guest Configuration content artifact (.zip)
40
+ - Automated testing of the artifact
41
+ - Creating a policy definition
42
+ - Publishing the policy
43
+
44
+ The module can be installed on a machine running Windows, macOS, or Linux with
39
45
PowerShell 6.2 or later running locally, or with [ Azure Cloud Shell] ( https://shell.azure.com ) , or
40
46
with the
41
47
[ Azure PowerShell Core Docker image] ( https://hub.docker.com/r/azuresdk/azure-powershell-core ) .
@@ -228,7 +234,7 @@ AuditBitLocker ./Config
228
234
```
229
235
230
236
Save this file with name ` config.ps1 ` in the project folder. Run it in PowerShell by executing ` ./config.ps1 `
231
- in the terminal. A new mof file will be created.
237
+ in the terminal. A new mof file is created.
232
238
233
239
The ` Node AuditBitlocker ` command isn't technically required but it produces a file named
234
240
` AuditBitlocker.mof ` rather than the default, ` localhost.mof ` . Having the .mof file name follow the
@@ -259,8 +265,7 @@ development environment as is used inside Azure machines. Using this solution, y
259
265
integration testing locally before releasing to billed cloud environments.
260
266
261
267
Since the agent is actually evaluating the local environment, in most cases you need to run the
262
- Test- cmdlet on the same OS platform as you plan to audit. The test will only use modules that are included
263
- in the content package.
268
+ Test- cmdlet on the same OS platform as you plan to audit. The test only uses modules that are included in the content package.
264
269
265
270
Parameters of the ` Test-GuestConfigurationPackage ` cmdlet:
266
271
@@ -376,6 +381,15 @@ The following files are created by `New-GuestConfigurationPolicy`:
376
381
The cmdlet output returns an object containing the initiative display name and path of the policy
377
382
files.
378
383
384
+ > [ !Note]
385
+ > The latest Guest Configuration module includes a new parameters:
386
+ > - ** Tag** adds one or more tag filters to the policy definition
387
+ > - See the section [ Filtering Guest Configuration policies using Tags] ( #filtering-guest-configuration-policies-using-tags ) .
388
+ > - ** Category** sets the category metadata field in the policy definition
389
+ > - If the parameter is not included, the category defaults to Guest Configuration.
390
+ > These features are in preview and require Guest Configuration module
391
+ > version 1.20.1, which can be installed using ` Install-Module GuestConfiguration -AllowPrerelease ` .
392
+
379
393
Finally, publish the policy definitions using the ` Publish-GuestConfigurationPolicy ` cmdlet. The
380
394
cmdlet only has the ** Path** parameter that points to the location of the JSON files created by
381
395
` New-GuestConfigurationPolicy ` .
@@ -410,7 +424,7 @@ initiative with [Portal](../assign-policy-portal.md), [Azure CLI](../assign-poli
410
424
> assigned, the prerequisites aren't deployed and the policy always shows that '0' servers are
411
425
> compliant.
412
426
413
- Assigning an policy definition with _ DeployIfNotExists_ effect requires an additional level of
427
+ Assigning a policy definition with _ DeployIfNotExists_ effect requires an additional level of
414
428
access. To grant the least privilege, you can create a custom role definition that extends
415
429
** Resource Policy Contributor** . The example below creates a role named ** Resource Policy
416
430
Contributor DINE** with the additional permission _ Microsoft.Authorization/roleAssignments/write_ .
@@ -428,7 +442,42 @@ $role.AssignableScopes.Add("/subscriptions/$subscriptionid")
428
442
New-AzRoleDefinition -Role $role
429
443
```
430
444
431
- ### Using parameters in custom Guest Configuration policies
445
+ ### Filtering Guest Configuration policies using Tags
446
+
447
+ > [ !Note]
448
+ > This feature is in preview and requires Guest Configuration module
449
+ > version 1.20.1, which can be installed using ` Install-Module GuestConfiguration -AllowPrerelease ` .
450
+
451
+ The policy definitions created by cmdlets in the Guest Configuration module can optionally include
452
+ a filter for tags. The ** Tag** parameter of ` New-GuestConfigurationPolicy ` supports
453
+ an array of hashtables containing individual tag entires. The tags are added
454
+ to the ` If ` section of the policy definition and can not be modified by a policy assignment.
455
+
456
+ An example snippet of a policy definition that filters for tags is given below.
457
+
458
+ ``` json
459
+ "if" : {
460
+ "allOf" : [
461
+ {
462
+ "allOf" : [
463
+ {
464
+ "field" : " tags.Owner" ,
465
+ "equals" : " BusinessUnit"
466
+ },
467
+ {
468
+ "field" : " tags.Role" ,
469
+ "equals" : " Web"
470
+ }
471
+ ]
472
+ },
473
+ {
474
+ // Original Guest Configuration content
475
+ }
476
+ ]
477
+ }
478
+ ```
479
+
480
+ ### Using parameters in custom Guest Configuration policy definitions
432
481
433
482
Guest Configuration supports overriding properties of a Configuration at run time. This feature
434
483
means that the values in the MOF file in the package don't have to be considered static. The
@@ -466,6 +515,144 @@ New-GuestConfigurationPolicy
466
515
-Version 1.0.0
467
516
```
468
517
518
+ ## Extending Guest Configuration with third-party tools
519
+
520
+ > [ !Note]
521
+ > This feature is in preview and requires Guest Configuration module
522
+ > version 1.20.1, which can be installed using ` Install-Module GuestConfiguration -AllowPrerelease ` .
523
+ > In version 1.20.1, this feature is only available for policy definitions that audit Windows machines
524
+
525
+ The artifact packages for Guest Configuration can be extended to include third-party tools.
526
+ Extending Guest Configuration requires development of two components.
527
+
528
+ - A Desired State Configuration resource that handles all activity related to managing the third-party tool
529
+ - Install
530
+ - Invoke
531
+ - Convert output
532
+ - Content in the correct format for the tool to natively consume
533
+
534
+ The DSC resource requires custom development if a community solution does not already exist.
535
+ Community solutions can be discovered by searching the PowerShell Gallery for tag
536
+ [ GuestConfiguration] ( https://www.powershellgallery.com/packages?q=Tags%3A%22GuestConfiguration%22 ) .
537
+
538
+ > [ !Note]
539
+ > Guest Configuration extensibility is a "bring your own
540
+ > license" scenario. Ensure you have met the terms and conditions of any third
541
+ > party tools before use.
542
+
543
+ After the DSC resource has been installed in the development environment, use the
544
+ ** FilesToInclude** parameter for ` New-GuestConfigurationPackage ` to include
545
+ content for the third-party platform in the content artifact.
546
+
547
+ ### Step by step, creating a content artifact that uses third-party tools
548
+
549
+ Only the ` New-GuestConfigurationPackage ` cmdlet requires a change from
550
+ the step-by-step guidance for DSC content artifacts. For this example,
551
+ use the ` gcInSpec ` module to extend Guest Configuration to audit Windows machines
552
+ using the InSpec platform rather than the built-in module used on Linux. The
553
+ community module is maintained as an
554
+ [ open source project in GitHub] ( https://github.com/microsoft/gcinspec ) .
555
+
556
+ Install required modules in your development environment:
557
+
558
+ ``` azurepowershell-interactive
559
+ Install-Module GuestConfiguration, gcInSpec
560
+ ```
561
+
562
+ First, create the YaML file used by InSpec. The file provides basic information about the
563
+ environment. An example is given below:
564
+
565
+ ``` YaML
566
+ name : wmi_service
567
+ title : Verify WMI service is running
568
+ maintainer : Microsoft Corporation
569
+ summary : Validates that the Windows Service 'winmgmt' is running
570
+ copyright : Microsoft Corporation
571
+ license : MIT
572
+ version : 1.0.0
573
+ supports :
574
+ - os-family : windows
575
+ ` ` `
576
+
577
+ Save this file to a folder named ` wmi_service` in your project directory.
578
+
579
+ Next, create the Ruby file with the InSpec language abstraction used to audit the machine.
580
+
581
+ ` ` ` Ruby
582
+ control 'wmi_service' do
583
+ impact 1.0
584
+ title 'Verify windows service: winmgmt'
585
+ desc 'Validates that the service, is installed, enabled, and running'
586
+
587
+ describe service('winmgmt') do
588
+ it { should be_installed }
589
+ it { should be_enabled }
590
+ it { should be_running }
591
+ end
592
+ end
593
+
594
+ ` ` `
595
+
596
+ Save this file in a new folder named `controls` inside the `wmi_service` directory.
597
+
598
+ Finally, create a configuration, import the **GuestConfiguration** resource module, and use the
599
+ ` gcInSpec` resource to set the name of the InSpec profile.
600
+
601
+ ` ` ` powershell
602
+ # Define the configuration and import GuestConfiguration
603
+ Configuration wmi_service
604
+ {
605
+ Import-DSCResource -Module @{ModuleName = 'gcInSpec'; ModuleVersion = '2.0.0'}
606
+ node 'wmi_service'
607
+ {
608
+ gcInSpec wmi_service
609
+ {
610
+ InSpecProfileName = 'wmi_service'
611
+ InSpecVersion = '3.9.3'
612
+ WindowsServerVersion = '2016'
613
+ }
614
+ }
615
+ }
616
+
617
+ # Compile the configuration to create the MOF files
618
+ wmi_service -out ./Config
619
+ ` ` `
620
+
621
+ You should now have a project structure as below :
622
+
623
+ ` ` ` file
624
+ / wmi_service
625
+ / Config
626
+ wmi_service.mof
627
+ / wmi_service
628
+ wmi_service.yml
629
+ / controls
630
+ wmi_service.rb
631
+ ` ` `
632
+
633
+ The supporting files must be packaged together. The completed package is used by
634
+ Guest Configuration to create the Azure Policy definitions.
635
+
636
+ The `New-GuestConfigurationPackage` cmdlet creates the package. For third-party
637
+ content, use the **FilesToInclude** parameter to add the InSpec content to the
638
+ package. You do not need to specify the **ChefProfilePath** as for Linux packages.
639
+
640
+ - **Name**: Guest Configuration package name.
641
+ - **Configuration**: Compiled configuration document full path.
642
+ - **Path**: Output folder path. This parameter is optional. If not specified, the package is created
643
+ in current directory.
644
+ - **FilesoInclude**: Full path to InSpec profile.
645
+
646
+ Run the following command to create a package using the configuration given in
647
+ the previous step :
648
+
649
+ ` ` ` azurepowershell-interactive
650
+ New-GuestConfigurationPackage `
651
+ -Name 'wmi_service' `
652
+ -Configuration './Config/wmi_service.mof' `
653
+ -FilesToInclude './wmi_service'
654
+ ```
655
+
469
656
## Policy lifecycle
470
657
471
658
If you would like to release an update to the policy, there are two fields that require attention.
0 commit comments