I am trying to configure an Azure VM with Azure Automation DSC. One of the resources I want to set is DNS on the client workstation with xDnsServerAddress
from xNetworking
module.
The problem is that it requires an interface alias and interface aliases change on Azure VMs vary depending on deployment (mainly VMs seem to get either Ethernet
or Ethernet 2
).
I can query the interface name locally using the following cmdlet expression:
$Interface=Get-NetAdapter|Where Name -Like "Ethernet*"|Select-Object -First 1
$InterfaceAlias=$($Interface.Name)
I don't know, however, how to use it inside the DSC.
My DSC configuration is as below (only the relevant part):
Configuration MyDscConfig
{
Import-DscResource -ModuleName xNetworking
# place-1
Node $AllNodes.where{$_.Role -eq "Workstation"}.NodeName
{
# place-2
xDnsServerAddress DnsServerAddressSetToDc1
{
Address = '10.0.0.4'
InterfaceAlias = $InterfaceAlias
AddressFamily = 'IPv4'
Validate = $true
}
}
}
The problem is that if I place the cmdlet expression either in place-1
or place-2
the compilation job fails with:
The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: The term 'Get-NetAdapter' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
I assume it tries to execute Get-NetAdapter
on the pull server, but I may be misinterpreting the error message.
How can I register the result of the cmdlet expression on a destination machine and register it in $InterfaceAlias
variable for the xDnsServerAddress
resource?
You currently cannot perform a query keep the results of the operation and use it to declare the next state (See notes at the end of the answer.)
You can work around this limitation using the documented workaround/solution from xNetworking, which will find an active ethernet adapter named Ethernet1
if it does not, it will find the first active ethernet adapter and make sure it is named Ethernet1
. Then, use a resource to set the DSC server address on Ethernet1
.
This is investigational, names and parameters are subject to change. The DSC team is investigating a better way to do this.
Configuration SetDns
{
param
(
[string[]]$NodeName = 'localhost'
)
Import-DSCResource -ModuleName xNetworking
Node $NodeName
{
script NetAdapterName
{
GetScript = {
Import-module xNetworking
$getResult = Get-xNetworkAdapterName -Name 'Ethernet1'
return @{
result = $getResult
}
}
TestScript = {
Import-module xNetworking
Test-xNetworkAdapterName -Name 'Ethernet1'
}
SetScript = {
Import-module xNetworking
Set-xNetworkAdapterName -Name 'Ethernet1' -IgnoreMultipleMatchingAdapters
}
}
xDnsServerAddress DnsServerAddress
{
Address = '10.0.0.4'
InterfaceAlias = 'Ethernet1'
AddressFamily = 'IPv4'
DependsOn = @('[Script]NetAdapterName')
}
}
}
Notes:
There is a question in the comments. The summary of the question is if querying turns the declarative paradigm into an imperative paradigm.
Answer:
I don't believe querying turns it into an imperative paradigm, but you currently cannot perform a query keep the results of the operation and use it to declare the next state.
This currently forces us into something a little further away from declarative for the problem that I would like. My personal opinion is that we should work with what we have and write resources that query and set a known state. Then, use the known state through the rest of the configuration (a form a declarative-relative, per your terminology).
The DSC team has this similar UserVoice suggestion we are using to track this request. Please upvote it if you think this is a useful feature.