puppetlabs / ruby-pwsh

A ruby gem for interacting with PowerShell
MIT License
15 stars 23 forks source link

NetworkingDSC\NetAdapterName - Unable to rename more than one NetAdapter #184

Closed norbertstoll closed 2 years ago

norbertstoll commented 2 years ago

Describe the Bug

It's impossible to rename a network adapter if there's more than one network adapter installed.

It doesn't make any difference if I add the MacAddresses, the InterfaceIndexes, the InterfaceNumbers or whatever - it will always fail as long as there's more than one NIC installed.

Seems like there's an issue with the parameter 'IgnoreMultipleMatchingAdapters' within NetworkingDsc's NetAdapterName.

Expected Behavior

Adapters, independent of the total amount of NICs, are being renamed as defined.

Steps to Reproduce

  1. Config in hiera:
    profile::dsc::networking::netadaptername:
    'Rename Ethernet0': 
    dsc_name: 'Ethernet0'
    dsc_newname: 'LAN1'
    dsc_ignoremultiplematchingadapters: true
    'Rename Ethernet1':
    dsc_name: 'Ethernet1'
    dsc_newname: 'LAN2'
    dsc_ignoremultiplematchingadapters: true
  2. Output of puppet agent -t:

2.1 Output of a puppet run with only one network adapter installed: ('Ethernet0' is renamed successfully, 'Ethernet1' fails because it doesn't exist yet - fine.)

PS C:> puppet agent -t Info: Using configured environment 'dev' Info: Retrieving pluginfacts Info: Retrieving plugin Info: Retrieving locales Info: Loading facts Info: Caching catalog for fqdn Info: Applying configuration version 'f053cc66403cf52943c6d4bcfd56c39db2a9c815' Notice: /Stage[main]/Profile::Dsc::Networking/Dsc_netadaptername[Rename Ethernet0]/dsc_name: dsc_name changed to 'Ethernet0' (corrective) Notice: /Stage[main]/Profile::Dsc::Networking/Dsc_netadaptername[Rename Ethernet0]/dsc_ignoremultiplematchingadapters: dsc_ignoremultiplematchingadapters changed to 'true' (corrective) Notice: dsc_netadaptername[{:name=>"Rename Ethernet0", :dsc_newname=>"LAN1"}]: Updating: Finished in 0.743496 seconds Notice: /Stage[main]/Profile::Dsc::Networking/Dsc_netadaptername[Rename Ethernet1]/dsc_name: dsc_name changed to 'Ethernet1' Notice: /Stage[main]/Profile::Dsc::Networking/Dsc_netadaptername[Rename Ethernet1]/dsc_ignoremultiplematchingadapters: dsc_ignoremultiplematchingadapters changed to 'true' Error: dsc_netadaptername[{:name=>"Rename Ethernet1", :dsc_newname=>"LAN2"}]: Updating: PowerShell DSC resource DSC_NetAdapterName failed to execute Set-TargetResource functionality with error message: System.InvalidOperationException: A network adapter matching the parameters was not found. Please correct the properties and try again. Notice: dsc_netadaptername[{:name=>"Rename Ethernet1", :dsc_newname=>"LAN2"}]: Updating: Finished in 0.827758 seconds Notice: Applied catalog in 4.60 seconds PS C:>

2.2 Output of a puppet run with a second network adapter installed:

PS C:> puppet agent -t Info: Using configured environment 'dev' Info: Retrieving pluginfacts Info: Retrieving plugin Info: Retrieving locales Info: Loading facts Error: dsc_netadaptername: PowerShell DSC resource DSC_NetAdapterName failed to execute Get-TargetResource functionality with error message: System.InvalidOperationException: Please adjust the parameters or specify IgnoreMultipleMatchingAdapters to only use the first and try again. Info: Caching catalog for fqdn Info: Applying configuration version 'f053cc66403cf52943c6d4bcfd56c39db2a9c815' Notice: /Stage[main]/Profile::Dsc::Networking/Dsc_netadaptername[Rename Ethernet0]/dsc_name: dsc_name changed to 'Ethernet0' (corrective) Notice: /Stage[main]/Profile::Dsc::Networking/Dsc_netadaptername[Rename Ethernet0]/dsc_ignoremultiplematchingadapters: dsc_ignoremultiplematchingadapters changed to 'true' (corrective) Error: dsc_netadaptername[{:name=>"Rename Ethernet0", :dsc_newname=>"LAN1"}]: Updating: PowerShell DSC resource DSC_NetAdapterName failed to execute Set-TargetResource functionality with error message: System.InvalidOperationException: A network adapter matching the parameters was not found. Please correct the properties and try again. Notice: dsc_netadaptername[{:name=>"Rename Ethernet0", :dsc_newname=>"LAN1"}]: Updating: Finished in 0.714882 seconds Error: dsc_netadaptername: PowerShell DSC resource DSC_NetAdapterName failed to execute Get-TargetResource functionality with error message: System.InvalidOperationException: Please adjust the parameters or specify IgnoreMultipleMatchingAdapters to only use the first and try again. Error: /Stage[main]/Profile::Dsc::Networking/Dsc_netadaptername[Rename Ethernet1]: Could not evaluate: undefined method `[]' for nil:NilClass Info: Class[Profile::Dsc::Networking]: Unscheduling all events on Class[Profile::Dsc::Networking] Notice: Applied catalog in 3.77 seconds PS C:>

Environment

puppet agent 6.24.0 mod 'puppetlabs-pwshlib', '0.10.1' mod 'dsc-networkingdsc', '8.2.0-0-3'

Additional Context

The error can not be reproduced via PowerShell DSC in its native way.

  1. Config code:
Configuration RenameNIC
{
    Import-DSCResource -ModuleName NetworkingDsc

    Node localhost
    {
        NetAdapterName RenameNetAdapter1
        {
            NewName           = 'LAN1'
            Name              = 'Ethernet0'
            IgnoreMultipleMatchingAdapters = $true
        }   

        NetAdapterName RenameNetAdapter2
        {
            NewName           = 'LAN2'
            Name              = 'Ethernet1'
            IgnoreMultipleMatchingAdapters = $true
        }

    }
}
  1. Execution:
PS C:\DSC> Get-NetAdapter | Select -ExpandProperty Name
Ethernet0
Ethernet1
PS C:\DSC\> Start-DscConfiguration -Path .\RenameNIC -Wait -Verbose -Force
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 DSC01VP with user sid S-1-5-21-654969828-2688359824-3472641617-500.
VERBOSE: [DSC01VP]: LCM:  [ Start  Set      ]
VERBOSE: [DSC01VP]: LCM:  [ Start  Resource ]  [[NetAdapterName]RenameNetAdapter1]
VERBOSE: [DSC01VP]: LCM:  [ Start  Test     ]  [[NetAdapterName]RenameNetAdapter1]
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter1] Test-TargetResource: Testing the
network adapter Name 'LAN1'.
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter1] Find-NetworkAdapter: Finding network
 adapters matching the parameters.
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter1] Test-TargetResource: Finding network
 adapter matching search criteria.
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter1] Find-NetworkAdapter: Finding network
 adapters matching the parameters.
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter1] Find-NetworkAdapter: 1 network
adapters were found matching the parameters.
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter1] Test-TargetResource: network adapter
 Name 'Ethernet0' does not match the adapter 'LAN1' that was found. Rename required.
VERBOSE: [DSC01VP]: LCM:  [ End    Test     ]  [[NetAdapterName]RenameNetAdapter1]  in 1.1250 seconds.
VERBOSE: [DSC01VP]: LCM:  [ Start  Set      ]  [[NetAdapterName]RenameNetAdapter1]
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter1] Set-TargetResource: Setting the
network adapter Name 'LAN1'.
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter1] Find-NetworkAdapter: Finding network
 adapters matching the parameters.
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter1] Find-NetworkAdapter: 1 network
adapters were found matching the parameters.
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter1] Set-TargetResource: Renaming network
 adapter 'Ethernet0' to 'LAN1'.
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter1] Set-TargetResource: network adapter
renamed to 'LAN1'.
VERBOSE: [DSC01VP]: LCM:  [ End    Set      ]  [[NetAdapterName]RenameNetAdapter1]  in 0.1560 seconds.
VERBOSE: [DSC01VP]: LCM:  [ End    Resource ]  [[NetAdapterName]RenameNetAdapter1]
VERBOSE: [DSC01VP]: LCM:  [ Start  Resource ]  [[NetAdapterName]RenameNetAdapter2]
VERBOSE: [DSC01VP]: LCM:  [ Start  Test     ]  [[NetAdapterName]RenameNetAdapter2]
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter2] Test-TargetResource: Testing the
network adapter Name 'LAN2'.
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter2] Find-NetworkAdapter: Finding network
 adapters matching the parameters.
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter2] Test-TargetResource: Finding network
 adapter matching search criteria.
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter2] Find-NetworkAdapter: Finding network
 adapters matching the parameters.
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter2] Find-NetworkAdapter: 1 network
adapters were found matching the parameters.
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter2] Test-TargetResource: network adapter
 Name 'Ethernet1' does not match the adapter 'LAN2' that was found. Rename required.
VERBOSE: [DSC01VP]: LCM:  [ End    Test     ]  [[NetAdapterName]RenameNetAdapter2]  in 0.0470 seconds.
VERBOSE: [DSC01VP]: LCM:  [ Start  Set      ]  [[NetAdapterName]RenameNetAdapter2]
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter2] Set-TargetResource: Setting the
network adapter Name 'LAN2'.
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter2] Find-NetworkAdapter: Finding network
 adapters matching the parameters.
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter2] Find-NetworkAdapter: 1 network
adapters were found matching the parameters.
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter2] Set-TargetResource: Renaming network
 adapter 'Ethernet1' to 'LAN2'.
VERBOSE: [DSC01VP]:                            [[NetAdapterName]RenameNetAdapter2] Set-TargetResource: network adapter
renamed to 'LAN2'.
VERBOSE: [DSC01VP]: LCM:  [ End    Set      ]  [[NetAdapterName]RenameNetAdapter2]  in 0.0780 seconds.
VERBOSE: [DSC01VP]: LCM:  [ End    Resource ]  [[NetAdapterName]RenameNetAdapter2]
VERBOSE: [DSC01VP]: LCM:  [ End    Set      ]
VERBOSE: [DSC01VP]: LCM:  [ End    Set      ]    in  1.7340 seconds.
VERBOSE: Operation 'Invoke CimMethod' complete.
VERBOSE: Time taken for configuration job to complete is 2.297 seconds
PS C:\DSC> Get-NetAdapter | Select -ExpandProperty Name
LAN1
LAN2
PS C:\DSC>
michaeltlombardi commented 2 years ago

@norbertstoll have you tried running with the validation_mode flag set to resource per this documentation?

Looking at the source code for the resource, it looks like the only mandatory property is the NewName property (see below); because of the API surface of DSC and how Puppet has to interact with it, Puppet can't make assumptions about properties and parameters for edge cases, which this seems to be hitting.

https://github.com/dsccommunity/NetworkingDsc/blob/73cbeba1958b4aec89f8eaa7cfb83f7a5b23ab7d/source/DSCResources/DSC_NetAdapterName/DSC_NetAdapterName.schema.mof#L4

https://github.com/dsccommunity/NetworkingDsc/blob/73cbeba1958b4aec89f8eaa7cfb83f7a5b23ab7d/source/DSCResources/DSC_NetAdapterName/DSC_NetAdapterName.psm1#L59-L62

norbertstoll commented 2 years ago

@michaeltlombardi I already tried this but forgot to mention. Sorry! Adding validation_mode sadly didn't change the behaviour (though it helped a lot in the past regarding securitypolicydsc)

michaeltlombardi commented 2 years ago

@norbertstoll For this specific issue, I think the only short term solution might be to use puppetlabs/dsc_lite - this is a case where an optional parameter changes the underlying behavior in a way that is not predictably reported by the DSC Resource's API; for the autogenerator (and thereby, the base provider in this repo) to handle the behavior, there would need to be some sort of flag on the DSC Resource property which indicates that it should be passed to Get if specified; as-is, there's no way to distinguish this from any other optional parameter.

norbertstoll commented 2 years ago

@michaeltlombardi Understood. I'll try via _dsclite. Thanks anyway :)

michaeltlombardi commented 2 years ago

No problem!