Resource dependencies using DependsOn
When you write Configurations, you add
Resource blocks to configure aspects of a target Node. As you continue
to add Resource blocks, your Configurations can grow quite large and cumbersome to manage. One such
challenge is the applied order of your resource blocks. Typically resources are applied in the order
they are defined within the Configuration. As your Configuration grows larger and more complex, you
can use the DependsOn
key to change the applied order of your resources by specifying that a
resource depends on another resource.
The DependsOn
key can be used in any Resource block. It is defined with the same key/value
mechanism as other Resource keys. The DependsOn
key expects an array of strings with the following
syntax.
DependsOn = '[<Resource Type>]<Resource Name>', '[<Resource Type>]<Resource Name'
The following example configures a firewall rule after enabling and configuring the public profile.
# Install the NetworkingDSC module to configure firewall rules and profiles.
Install-Module -Name NetworkingDSC
Configuration ConfigureFirewall
{
Import-DSCResource -Name Firewall, FirewallProfile
Node localhost
{
Firewall Firewall
{
Name = 'IIS-WebServerRole-HTTP-In-TCP'
Ensure = 'Present'
Enabled = 'True'
DependsOn = '[FirewallProfile]FirewallProfilePublic'
}
FirewallProfile FirewallProfilePublic
{
Name = 'Public'
Enabled = 'True'
DefaultInboundAction = 'Block'
DefaultOutboundAction = 'Allow'
AllowInboundRules = 'True'
AllowLocalFirewallRules = 'False'
AllowLocalIPsecRules = 'False'
NotifyOnListen = 'True'
LogFileName = '%systemroot%\system32\LogFiles\Firewall\pfirewall.log'
LogMaxSizeKilobytes = 16384
LogAllowed = 'False'
LogBlocked = 'True'
LogIgnored = 'NotConfigured'
}
}
}
ConfigureFirewall -OutputPath C:\Temp\
When you apply the Configuration, the firewall profile will always be configured first regardless of which order the Resource blocks are defined. If you apply the Configuration, be sure to note your target Nodes existing Configuration so you can revert if desired.
PS> Start-DSCConfiguration -Verbose -Wait -Path C:\Temp\ -ComputerName localhost
VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = SendConfigurationApply,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'.
VERBOSE: An LCM method call arrived from computer SERVER01 with user sid S-1-5-21-181338-0189125723-1543119021-1282804.
VERBOSE: [SERVER01]: LCM: [ Start Set ]
VERBOSE: [SERVER01]: [DSCEngine] Importing the module C:\Program Files\WindowsPowerShell\Modules\NetworkingDsc\6.1.0.0\DscResources\MSFT_Firewall\MSFT_Firewall.psm1 in force mode.
VERBOSE: [SERVER01]: [DSCEngine] Importing the module C:\Program Files\WindowsPowerShell\Modules\NetworkingDsc\6.1.0.0\DscResources\MSFT_FirewallProfile\MSFT_FirewallProfile.psm1 in force mode.
VERBOSE: [SERVER01]: LCM: [ Start Resource ] [[FirewallProfile]FirewallProfilePublic]
VERBOSE: [SERVER01]: LCM: [ Start Test ] [[FirewallProfile]FirewallProfilePublic]
VERBOSE: [SERVER01]: [[FirewallProfile]FirewallProfilePublic] Importing the module MSFT_FirewallProfile in force mode.
VERBOSE: [SERVER01]: [[FirewallProfile]FirewallProfilePublic] Test-TargetResource: Testing Firewall Public Profile.
VERBOSE: [SERVER01]: [[FirewallProfile]FirewallProfilePublic] Test-TargetResource: Firewall Public Profile "AllowInboundRules" is "NotConfigured" but should be "True". Change required.
VERBOSE: [SERVER01]: [[FirewallProfile]FirewallProfilePublic] Test-TargetResource: Firewall Public Profile "AllowLocalFirewallRules" is "NotConfigured" but should be "False". Change required.
VERBOSE: [SERVER01]: [[FirewallProfile]FirewallProfilePublic] Test-TargetResource: Firewall Public Profile "AllowLocalIPsecRules" is "NotConfigured" but should be "False". Change required.
VERBOSE: [SERVER01]: [[FirewallProfile]FirewallProfilePublic] Test-TargetResource: Firewall Public Profile "DefaultOutboundAction" is "NotConfigured" but should be "Allow". Change required.
VERBOSE: [SERVER01]: [[FirewallProfile]FirewallProfilePublic] Test-TargetResource: Firewall Public Profile "LogBlocked" is "False" but should be "True". Change required.
VERBOSE: [SERVER01]: [[FirewallProfile]FirewallProfilePublic] Test-TargetResource: Firewall Public Profile "LogMaxSizeKilobytes" is "4096" but should be "16384". Change required.
VERBOSE: [SERVER01]: LCM: [ End Test ] [[FirewallProfile]FirewallProfilePublic] in 1.6890 seconds.
VERBOSE: [SERVER01]: LCM: [ Start Set ] [[FirewallProfile]FirewallProfilePublic]
VERBOSE: [SERVER01]: [[FirewallProfile]FirewallProfilePublic] Importing the module MSFT_FirewallProfile in force mode.
VERBOSE: [SERVER01]: [[FirewallProfile]FirewallProfilePublic] Set-TargetResource: Setting Firewall Public Profile.
VERBOSE: [SERVER01]: [[FirewallProfile]FirewallProfilePublic] Set-TargetResource: Setting Firewall Public Profile parameter AllowInboundRules to "AllowInboundRules".
VERBOSE: [SERVER01]: [[FirewallProfile]FirewallProfilePublic] Set-TargetResource: Setting Firewall Public Profile parameter AllowLocalFirewallRules to "AllowLocalFirewallRules".
VERBOSE: [SERVER01]: [[FirewallProfile]FirewallProfilePublic] Set-TargetResource: Setting Firewall Public Profile parameter AllowLocalIPsecRules to "AllowLocalIPsecRules".
VERBOSE: [SERVER01]: [[FirewallProfile]FirewallProfilePublic] Set-TargetResource: Setting Firewall Public Profile parameter DefaultOutboundAction to "DefaultOutboundAction".
VERBOSE: [SERVER01]: [[FirewallProfile]FirewallProfilePublic] Set-TargetResource: Setting Firewall Public Profile parameter LogBlocked to "LogBlocked".
VERBOSE: [SERVER01]: [[FirewallProfile]FirewallProfilePublic] Set-TargetResource: Setting Firewall Public Profile parameter LogMaxSizeKilobytes to "LogMaxSizeKilobytes".
VERBOSE: [SERVER01]: [[FirewallProfile]FirewallProfilePublic] Set-TargetResource: Setting Firewall Public Profile updated.
VERBOSE: [SERVER01]: LCM: [ End Set ] [[FirewallProfile]FirewallProfilePublic] in 10.0360 seconds.
VERBOSE: [SERVER01]: LCM: [ End Resource ] [[FirewallProfile]FirewallProfilePublic]
VERBOSE: [SERVER01]: LCM: [ Start Resource ] [[Firewall]Firewall]
VERBOSE: [SERVER01]: LCM: [ Start Test ] [[Firewall]Firewall]
VERBOSE: [SERVER01]: [[Firewall]Firewall] Importing the module MSFT_Firewall in force mode.
VERBOSE: [SERVER01]: [[Firewall]Firewall] Test-TargetResource: Checking settings for firewall rule with Name 'IIS-WebServerRole-HTTP-In-TCP'.
VERBOSE: [SERVER01]: [[Firewall]Firewall] Test-TargetResource: Find firewall rule with Name 'IIS-WebServerRole-HTTP-In-TCP'.
VERBOSE: [SERVER01]: [[Firewall]Firewall] Get-FirewallRule: No Firewall Rule found with Name 'IIS-WebServerRole-HTTP-In-TCP'.
VERBOSE: [SERVER01]: [[Firewall]Firewall] Test-TargetResource: Firewall rule with Name 'IIS-WebServerRole-HTTP-In-TCP' does not exist.
VERBOSE: [SERVER01]: [[Firewall]Firewall] Test-TargetResource: Check Firewall rule with Name 'IIS-WebServerRole-HTTP-In-TCP' returning False.
VERBOSE: [SERVER01]: LCM: [ End Test ] [[Firewall]Firewall] in 1.1780 seconds.
VERBOSE: [SERVER01]: LCM: [ Start Set ] [[Firewall]Firewall]
VERBOSE: [SERVER01]: [[Firewall]Firewall] Importing the module MSFT_Firewall in force mode.
VERBOSE: [SERVER01]: [[Firewall]Firewall] Set-TargetResource: Applying settings for firewall rule with Name 'IIS-WebServerRole-HTTP-In-TCP'.
VERBOSE: [SERVER01]: [[Firewall]Firewall] Set-TargetResource: Find firewall rule with Name 'IIS-WebServerRole-HTTP-In-TCP'.
VERBOSE: [SERVER01]: [[Firewall]Firewall] Get-FirewallRule: No Firewall Rule found with Name 'IIS-WebServerRole-HTTP-In-TCP'.
VERBOSE: [SERVER01]: [[Firewall]Firewall] Set-TargetResource: We want the firewall rule with Name 'IIS-WebServerRole-HTTP-In-TCP' to exist since Ensure is set to Present.
VERBOSE: [SERVER01]: [[Firewall]Firewall] Set-TargetResource: We want the firewall rule with Name 'IIS-WebServerRole-HTTP-In-TCP' to exist, but it does not.
VERBOSE: [SERVER01]: [[Firewall]Firewall] New-NetFirewallRule DisplayName: IIS-WebServerRole-HTTP-In-TCP
VERBOSE: [SERVER01]: LCM: [ End Set ] [[Firewall]Firewall] in 1.0850 seconds.
VERBOSE: [SERVER01]: LCM: [ End Resource ] [[Firewall]Firewall]
VERBOSE: [SERVER01]: LCM: [ End Set ]
VERBOSE: [SERVER01]: LCM: [ End Set ] in 15.2880 seconds.
VERBOSE: Operation 'Invoke CimMethod' complete.
VERBOSE: Time taken for configuration job to complete is 15.385 seconds
This also ensures that if the FirewallProfile resource fails for any reason, the Firewall
block will not execute even though it was defined first. The DependsOn
key allows more flexibility
in grouping resource blocks and ensuring that dependencies are resolved before a Resource executes.
In more advanced Configurations, you can also use Cross Node Dependency to allow even more granular control (For example, ensuring a domain controller is configured before joining a client to the domain).
Cleaning Up
If you applied the Configuration above, you can reverse keys to undo any changes. In the above example, setting the Enabled key to false will disable the firewall rule and profile. You should modify the example as needed to match your target Node's previous configured state.
Firewall Firewall
{
Name = 'IIS-WebServerRole-HTTP-In-TCP'
Enabled = 'False'
DependsOn = '[FirewallProfile]FirewallProfilePublic'
}
FirewallProfile FirewallProfilePublic
{
Name = 'Public'
Enabled = 'False'
}