Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xDFSReplicationGroup - Error while comparing array containing $null #27

Closed
solbirn opened this issue Apr 26, 2017 · 14 comments · Fixed by #63
Closed

xDFSReplicationGroup - Error while comparing array containing $null #27

solbirn opened this issue Apr 26, 2017 · 14 comments · Fixed by #63
Assignees
Labels
bug The issue is a bug. in progress The issue is being actively worked on by someone.

Comments

@solbirn
Copy link

solbirn commented Apr 26, 2017

In xDFSReplicationGroup Test-TargetResource the following code can set $ExistingFolders to a @($null) array when the replication group does not yet contain folders. This results in a ParameterBindingValidation exception while subsequently evaluating the Compare-Object just below it.

# Compare the Folders
$ExistingFolders = @((Get-DfsReplicatedFolder @Splat -ErrorAction Stop).FolderName)
if ((Compare-Object `
    -ReferenceObject $Folders `
    -DifferenceObject $ExistingFolders).Count -ne 0)

Error message;

Compare-Object : Cannot bind argument to parameter 'ReferenceObject' because it is null.
    + CategoryInfo          : InvalidData: (:) [Compare-Object], ParameterBindingValidation
   Exception
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.Powe
   rShell.Commands.CompareObjectCommand

Can be resolved with:
$ExistingFolders = @((Get-DfsReplicatedFolder @Splat -ErrorAction Stop).FolderName) | where { $_ -ne $null }

@PlagueHO PlagueHO self-assigned this Apr 27, 2017
@PlagueHO PlagueHO added bug The issue is a bug. help wanted The issue is up for grabs for anyone in the community. labels Apr 27, 2017
@PlagueHO
Copy link
Member

Thanks @solbirn - I'll get this sorted this weekend. Thanks muchly for submitting this.

@PlagueHO
Copy link
Member

Hi @solbirn - I'll work on this once this PR is merged (should be over the next few days).

@PlagueHO
Copy link
Member

Hi @solbirn - I've been looking into this error and I'm not sure it is caused by this problem. Looking at the error message it is reporting that the ReferenceObject is null - this is the folders you should be passing into the Resource itself - rather than the existing Folders. Are you able to post your config so I can take a look?

@solbirn
Copy link
Author

solbirn commented May 29, 2017

Hi @PlagueHO,

Below is the config. I know this is the issue as I resolved in our environment by using a modified version of xDFS with $nulls removed from $ExisitingFolders, but I try to get you the full error as well.

Configuration DFSRConfig
{
    Param 
    ( 
        [String[]]
        $NodeName = "localhost",
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [String]
        $GroupName,
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [String[]]
        $DFSMembers,
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [PSCredential]
        $Credential,
        [String]
        $DomainName = $env:USERDNSDOMAIN
    )

    Import-DscResource -ModuleName PSDesiredStateConfiguration, xDFS

    Node $NodeName 
    {
        if($DFSMembers.Length -eq 2){
            WaitForAll DomainJoin 
            {
                ResourceName = "[xComputer]JoinDomain"
                NodeName = $NodeName
                RetryIntervalSec = 30
                RetryCount = 0
            }

            WaitForAll WaitDCPromo
            {
                ResourceName = "[xADDomainController]NewDC"
                NodeName = $NodeName
                RetryIntervalSec = 30
                RetryCount = 0
            }
        
            WindowsFeature InstallDFSR
            {
                Name = "FS-DFS-Replication"
                Ensure = "Present"
            }

            WindowsFeature InstallDFSRTools
            {
                Name = "RSAT-DFS-Mgmt-Con"
                Ensure = "Present"
            }

            xDFSReplicationGroup DFSRBackupReplicationGroup
            {
                GroupName = $GroupName
                Description = "$GroupName "
                Ensure = 'Present'
                Members = $DFSMembers
                Folders = 'SharedData','UserData'
                DomainName = $DomainName
                DependsOn = @("[WindowsFeature]InstallDFSR","[WindowsFeature]InstallDFSRTools","[WaitForAll]WaitDCPromo")
            }

            xDFSReplicationGroupConnection DFSRBackupReplicationConnectionSource
            {
                GroupName = $GroupName
                Ensure = 'Present'
                EnsureEnabled = 'Enabled'
                SourceComputerName = $DFSMembers[0]
                DestinationComputerName = $DFSMembers[1]
                DependsOn = '[xDFSReplicationGroup]DFSRBackupReplicationGroup'
            }

            xDFSReplicationGroupConnection DFSRBackupReplicationConnectionDestination
            {
                GroupName = $GroupName
                Ensure = 'Present'
                EnsureEnabled = 'Enabled'
                SourceComputerName = $DFSMembers[1]
                DestinationComputerName = $DFSMembers[0]
                DependsOn = '[xDFSReplicationGroup]DFSRBackupReplicationGroup'
            }

            xDFSReplicationGroupFolder DFSRBackupReplicationFolderSharedData
            {
                GroupName = $GroupName
                FolderName = "SharedData"
                Description = "Site specific shared data"
                DependsOn = '[xDFSReplicationGroup]DFSRBackupReplicationGroup'
            }

            xDFSReplicationGroupFolder DFSRBackupReplicationFolderUserData
            {
                GroupName = $GroupName
                FolderName = "UserData"
                Description = "Site specific user data"
                DependsOn = '[xDFSReplicationGroup]DFSRBackupReplicationGroup'
            }

            xDFSReplicationGroupMembership DFSRBackupReplicationMembershipSharedDataPrimary
            {
                GroupName = $GroupName
                FolderName = 'SharedData'
                ComputerName = $DFSMembers[0]
                ContentPath = 'D:\SharedData'
                PrimaryMember = $true
                DependsOn = '[xDFSReplicationGroupFolder]DFSRBackupReplicationFolderSharedData'
            }

            xDFSReplicationGroupMembership DFSRBackupReplicationMembershipSharedDataSecondary
            {
                GroupName = $GroupName
                FolderName = 'SharedData'
                ComputerName = $DFSMembers[1]
                ContentPath = "D:\$GroupName\SharedData"
                PsDscRunAsCredential = $Credential
                DependsOn = '[xDFSReplicationGroupMembership]DFSRBackupReplicationMembershipSharedDataPrimary'
            }

            xDFSReplicationGroupMembership DFSRBackupReplicationMembershipUserDataPrimary
            {
                GroupName = $GroupName
                FolderName = 'UserData'
                ComputerName = $DFSMembers[0]
                ContentPath = 'D:\UserData'
                PrimaryMember = $true
                DependsOn = '[xDFSReplicationGroupFolder]DFSRBackupReplicationFolderUserData'
            }

            xDFSReplicationGroupMembership DFSRBackupReplicationMembershipUserDataSecondary
            {
                GroupName = $GroupName
                FolderName = 'UserData'
                ComputerName = $DFSMembers[1]
                ContentPath = "D:\$GroupName\UserData"
                PsDscRunAsCredential = $Credential
                DependsOn = '[xDFSReplicationGroupMembership]DFSRBackupReplicationMembershipUserDataPrimary'
            }
        }
    }
}

@PlagueHO
Copy link
Member

PlagueHO commented Jun 3, 2017

Oh cool! Thank you @solbirn - that is much appreciated. I'll take a look into this this weekend!

@PlagueHO
Copy link
Member

PlagueHO commented Jun 9, 2017

Hi @solbirn - I'm having trouble writing any unit/regression tests that replicate this issue. I'm also having trouble replicating this issue on any WS 2016 DFS servers. I'm a bit worried about making the change above because I'm not actually sure why it would actually work (I might be being dumb though). I've checked through this every way and I do think the error you're seeing might be being caused by something else.

Could you answer the following questions for me to help me solve this:
Are you able to output the verbose logs of applying the above config at all?
What is the array $DFSRMembers being passed in as?
Which version of xDFS you are testing with?
What OS are you applying this on (WS 2012 R2, WS 2016 etc)?

Sorry I haven't managed to figure this out yet.

@murrahjm
Copy link
Contributor

Just ran into this error, though I think I'm hitting the issue around line 630 where it checks for differences in membership. I have a dfs replication group with no existing members, and using DFSReplicationGroup resource to specify two members. The line $existingMembers = @((Get-DfsrMember @replicationGroupParameters -ErrorAction Stop).DnsName) is returning a null value, and rightly so. But the line Compare-Object -ReferenceObject $fqdnMembers -DifferenceObject $existingMembers is throwing the error Cannot bind argument to parameter 'DifferenceObject' because it is null.

My first thought would be to check if either $existingmembers or $fqdnMembers is null before trying to compare them. If either are null then there is a difference and no further comparison is needed.

I suppose if they're both null then it could be the same but not sure there's a use case for ensuring that a replication group has no members.

solbirn added a commit to techkeys/DFSDsc that referenced this issue May 17, 2018
@PlagueHO
Copy link
Member

Hi @murrahjm - do you know the version of Windows Server you are running? I was never able to replicate the issue so wasn't able to confirm if the fix would resolve it or not (e.g. I couldn't write tests to confirm this).

@murrahjm
Copy link
Contributor

murrahjm commented May 18, 2018 via email

@PlagueHO
Copy link
Member

Hi @murrahjm - it should work being used in an Ansible playbook OK (or at least I'd want it to).

So to confirm, you actually created the replication group as an empty group first with no members or anything manually and then ran the playbook? That is a scenario I didn't actually test so it may indeed cause an error. I'm just in the process of spinning up a DFS environment to do some other testing, so I'll check this scenario.

@murrahjm
Copy link
Contributor

murrahjm commented May 19, 2018 via email

@murrahjm
Copy link
Contributor

Also I have an update that fixes the null comparison issue if you'd like a pull request. Not sure how it fares against all the other scenarios but it should be relatively benign.

@PlagueHO
Copy link
Member

Hi @murrahjm - sure - would be delighted to accept a PR (see https://github.com/PowerShell/DscResources/blob/master/CONTRIBUTING.md). But with a change like this it would be good to validate against the integration tests (https://github.com/PowerShell/DFSDsc/blob/dev/Tests/Integration/MSFT_DFSReplicationGroup.Integration.Tests.ps1). The integration tests do need to be run outside of AppVeyor CI because it needs two DFS server nodes to check against. I'm spinning up a test environment at the moment, so if you can submit your PR I can run some checks against the a real environment.

murrahjm added a commit to murrahjm/DFSDsc that referenced this issue May 21, 2018
Potentially solves dsccommunity#27.  Add section to check for null values in existing member list or proposed member list before using compare-object.  Also added same logic to the comparison of existing and proposed folder list.
@PlagueHO PlagueHO added in progress The issue is being actively worked on by someone. and removed help wanted The issue is up for grabs for anyone in the community. labels May 22, 2018
@PlagueHO
Copy link
Member

I can confirm that I can replicate this now by taking a deployed Replication Group and removing all the members from it and then reapplying the config. I'm now going to make @murrahjm changes to my copy and check it resolves the issue without any regression of other functions.

murrahjm added a commit to murrahjm/DFSDsc that referenced this issue May 30, 2018
Potentially solves dsccommunity#27.  Add section to check for null values in existing member list or proposed member list before using compare-object.  Also added same logic to the comparison of existing and proposed folder list.

style corrections

add tests for null members and null folders

correct issue number
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug The issue is a bug. in progress The issue is being actively worked on by someone.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants