Files
PowerShell-PSDscResources/Tests/TestHelpers/MSFT_GroupResource.TestHelper.psm1

833 lines
20 KiB
PowerShell

$errorActionPreference = 'Stop'
Set-StrictMode -Version 'Latest'
#Import CommonResourceHelper for Test-IsNanoServer
$moduleRootFilePath = Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent
$dscResourcesFolderFilePath = Join-Path -Path $moduleRootFilePath -ChildPath 'DSCResources'
$commonResourceHelperFilePath = Join-Path -Path $dscResourcesFolderFilePath -ChildPath 'CommonResourceHelper.psm1'
Import-Module -Name $commonResourceHelperFilePath
if (-not (Test-IsNanoServer))
{
Add-Type -AssemblyName 'System.DirectoryServices.AccountManagement'
}
<#
.SYNOPSIS
Tests if a Windows group with the given name and members exists.
.PARAMETER GroupName
The name of the group.
.PARAMETER Members
The usernames of the members of the group.
.PARAMETER MembersToInclude
The usernames of the members that should be included in the group.
.PARAMETER MembersToExclude
The usernames of the members that should be excluded from the group.
#>
function Test-GroupExists
{
[OutputType([System.Boolean])]
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[System.String]
$GroupName,
[Parameter()]
[System.String[]]
$Members,
[Parameter()]
[System.String[]]
$MembersToInclude,
[Parameter()]
[System.String[]]
$MembersToExclude
)
if (Test-IsNanoServer)
{
return Test-GroupExistsOnNanoServer @PSBoundParameters
}
else
{
return Test-GroupExistsOnFullSKU @PSBoundParameters
}
}
<#
.SYNOPSIS
Tests if a Windows group with the given name and members exists.
.PARAMETER GroupName
The name of the group.
.PARAMETER Members
The usernames of the members of the group.
.PARAMETER MembersToInclude
The usernames of the members that should be included in the group.
.PARAMETER MembersToExclude
The usernames of the members that should be excluded from the group.
#>
function Test-GroupExistsOnFullSKU
{
[OutputType([System.Boolean])]
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.String]
$GroupName,
[Parameter()]
[System.String[]]
$Members,
[Parameter()]
[System.String[]]
$MembersToInclude,
[Parameter()]
[System.String[]]
$MembersToExclude
)
$principalContext = New-Object -TypeName 'System.DirectoryServices.AccountManagement.PrincipalContext' `
-ArgumentList @( [System.DirectoryServices.AccountManagement.ContextType]::Machine )
$group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($principalContext, $GroupName)
$groupExists = $null -ne $group
if ($groupExists)
{
if ($PSBoundParameters.ContainsKey('Members'))
{
$noActualMembers = ($null -eq $group.Members) -or ($group.Members.Count -eq 0)
$noExpectedMembers = ($null -eq $Members) -or ($Members.Count -eq 0)
if ($noActualMembers -and $noExpectedMembers)
{
$membersMatch = $true
}
elseif ($noActualMembers -xor $noExpectedMembers)
{
$membersMatch = $false
}
else
{
$membersMatch = $null -eq (Compare-Object -ReferenceObject $Members -DifferenceObject $group.Members.Name)
}
$groupExists = $groupExists -and $membersMatch
}
if ($PSBoundParameters.ContainsKey('MembersToInclude'))
{
$noActualMembers = ($null -eq $group.Members) -or ($group.Members.Count -eq 0)
$noExpectedMembers = ($null -eq $MembersToInclude) -or ($MembersToInclude.Count -eq 0)
if ($noExpectedMembers)
{
$membersToIncludeMatch = $true
}
elseif ($noActualMembers)
{
$membersToIncludeMatch = $false
}
else
{
$membersToIncludeMatch = $true
foreach ($expectedMemberName in $MembersToInclude)
{
if ($group.Members.Name -inotcontains $expectedMemberName)
{
$membersToIncludeMatch = $false
break
}
}
}
$groupExists = $groupExists -and $membersToIncludeMatch
}
if ($PSBoundParameters.ContainsKey('MembersToExclude'))
{
$noActualMembers = ($null -eq $group.Members) -or ($group.Members.Count -eq 0)
$noExcludedMembers = ($null -eq $MembersToExclude) -or ($MembersToExclude.Count -eq 0)
if ($noExcludedMembers)
{
$membersToExcludeMatch = $true
}
elseif ($noActualMembers)
{
$membersToExcludeMatch = $true
}
else
{
$groupMemberNames = $group.Members.Name | ForEach-Object { ($_ -split '/')[-1] }
$membersToExcludeMatch = $true
foreach ($excludedMemberName in $MembersToExclude)
{
if ($group.Members.Name -icontains $excludedMemberName)
{
$membersToExcludeMatch = $false
break
}
}
}
$groupExists = $groupExists -and $membersToExcludeMatch
}
}
$null = $principalContext.Dispose()
return $groupExists
}
<#
.SYNOPSIS
Tests if a Windows group with the given name and members exists.
.PARAMETER GroupName
The name of the group.
.PARAMETER Members
The usernames of the members of the group.
.PARAMETER MembersToInclude
The usernames of the members that should be included in the group.
.PARAMETER MembersToExclude
The usernames of the members that should be excluded from the group.
#>
function Test-GroupExistsOnNanoServer
{
[OutputType([System.Boolean])]
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.String]
$GroupName,
[Parameter()]
[System.String[]]
$Members,
[Parameter()]
[System.String[]]
$MembersToInclude,
[Parameter()]
[System.String[]]
$MembersToExclude
)
$groupExists = $true
try
{
$null = Get-LocalGroup -Name $GroupName
}
catch [System.Exception]
{
if ($_.CategoryInfo.ToString().Contains('GroupNotFoundException'))
{
$groupExists = $false
}
else
{
throw $_.Exception
}
}
if ($groupExists)
{
if ($PSBoundParameters.ContainsKey('Members'))
{
$groupMembers = Get-LocalGroupMember -Group $Group
$noActualMembers = ($null -eq $groupMembers) -or ($groupMembers.Count -eq 0)
$noExpectedMembers = ($null -eq $Members) -or ($Members.Count -eq 0)
if ($noActualMembers -and $noExpectedMembers)
{
$membersMatch = $true
}
elseif ($noActualMembers -xor $noExpectedMembers)
{
$membersMatch = $false
}
else
{
$groupMemberNames = $groupMembers.Name | ForEach-Object { ($_ -split '/')[-1] }
$membersMatch = $null -eq (Compare-Object -ReferenceObject $Members -DifferenceObject $groupMemberNames)
}
$groupExists = $groupExists -and $membersMatch
}
if ($PSBoundParameters.ContainsKey('MembersToInclude'))
{
$groupMembers = Get-LocalGroupMember -Group $Group
$noActualMembers = ($null -eq $groupMembers) -or ($groupMembers.Count -eq 0)
$noExpectedMembers = ($null -eq $MembersToInclude) -or ($MembersToInclude.Count -eq 0)
if ($noExpectedMembers)
{
$membersToIncludeMatch = $true
}
elseif ($noActualMembers)
{
$membersToIncludeMatch = $false
}
else
{
$groupMemberNames = $groupMembers.Name | ForEach-Object { ($_ -split '/')[-1] }
$membersToIncludeMatch = $true
foreach ($expectedMemberName in $MembersToInclude)
{
if ($groupMemberNames -inotcontains $expectedMemberName)
{
$membersToIncludeMatch = $false
break
}
}
}
$groupExists = $groupExists -and $membersToIncludeMatch
}
if ($PSBoundParameters.ContainsKey('MembersToExclude'))
{
$groupMembers = Get-LocalGroupMember -Group $Group
$noActualMembers = ($null -eq $groupMembers) -or ($groupMembers.Count -eq 0)
$noExcludedMembers = ($null -eq $MembersToExclude) -or ($MembersToExclude.Count -eq 0)
if ($noExcludedMembers)
{
$membersToExcludeMatch = $true
}
elseif ($noActualMembers)
{
$membersToExcludeMatch = $true
}
else
{
$groupMemberNames = $groupMembers.Name | ForEach-Object { ($_ -split '/')[-1] }
$membersToExcludeMatch = $true
foreach ($excludedMemberName in $MembersToExclude)
{
if ($groupMemberNames -icontains $excludedMemberName)
{
$membersToExcludeMatch = $false
break
}
}
}
$groupExists = $groupExists -and $membersToExcludeMatch
}
}
return $groupExists
}
<#
.SYNOPSIS
Creates a Windows group.
.PARAMETER GroupName
The name of the group.
.PARAMETER Description
The description of the group.
.PARAMETER Members
The usernames of the members to add to the group.
#>
function New-Group
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.String]
$GroupName,
[Parameter()]
[System.String]
$Description,
[Parameter()]
[System.String[]]
$Members
)
if (Test-GroupExists -GroupName $GroupName)
{
throw "Group $GroupName already exists."
}
if (Test-IsNanoServer)
{
New-GroupOnNanoServer @PSBoundParameters
}
else
{
New-GroupOnFullSKU @PSBoundParameters
}
}
<#
.SYNOPSIS
Creates a Windows group on a full server.
.PARAMETER GroupName
The name of the group.
.PARAMETER Description
The description of the group.
.PARAMETER Members
The usernames of the members to add to the group.
#>
function New-GroupOnFullSKU
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.String]
$GroupName,
[Parameter()]
[System.String]
$Description,
[Parameter()]
[System.String[]]
$Members
)
$adsiComputerEntry = [System.DirectoryServices.DirectoryEntry] "WinNT://$env:computerName"
$adsiGroupEntry = $adsiComputerEntry.Create('Group', $GroupName)
if ($PSBoundParameters.ContainsKey('Description'))
{
$null = $adsiGroupEntry.Put('Description', $Description)
}
$null = $adsiGroupEntry.SetInfo()
if ($PSBoundParameters.ContainsKey("Members"))
{
$adsiGroupEntry = [System.DirectoryServices.DirectoryEntry] "WinNT://$env:computerName/$GroupName,group"
foreach ($memberUserName in $Members)
{
$null = $adsiGroupEntry.Add("WinNT://$env:computerName/$memberUserName")
}
}
}
<#
.SYNOPSIS
Creates a Windows group on a Nano server.
.PARAMETER GroupName
The name of the group.
.PARAMETER Description
The description of the group.
.PARAMETER Members
The usernames of the members to add to the group.
#>
function New-GroupOnNanoServer
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.String]
$GroupName,
[Parameter()]
[System.String]
$Description,
[Parameter()]
[System.String[]]
$Members
)
$null = New-LocalGroup -Name $GroupName
if ($PSBoundParameters.ContainsKey('Description'))
{
$null = Set-LocalGroup -Name $GroupName -Description $Description
}
if ($PSBoundParameters.ContainsKey('Members'))
{
$null = Add-LocalGroupMember -Name $GroupName -Member $Members
}
}
<#
.SYNOPSIS
Deletes a Windows group.
.PARAMETER GroupName
The name of the group.
#>
function Remove-Group
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.String]
$GroupName
)
if (-not (Test-GroupExists -GroupName $GroupName))
{
throw "Group $GroupName does not exist to remove."
}
if (Test-IsNanoServer)
{
Remove-GroupOnNanoServer @PSBoundParameters
}
else
{
Remove-GroupOnFullSKU @PSBoundParameters
}
}
<#
.SYNOPSIS
Deletes a Windows group on a full server.
.PARAMETER GroupName
The name of the group.
#>
function Remove-GroupOnFullSKU
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.String]
$GroupName
)
$adsiComputerEntry = [System.DirectoryServices.DirectoryEntry] ("WinNT://$env:computerName")
$null = $adsiComputerEntry.Delete('Group', $GroupName)
}
<#
.SYNOPSIS
Deletes a Windows group on a Nano server.
.PARAMETER GroupName
The name of the group.
#>
function Remove-GroupOnNanoServer
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.String]
$GroupName
)
Remove-LocalGroup -Name $GroupName
}
<#
.SYNOPSIS
Tests if a user with the given username exists.
.PARAMETER Username
The username of the user.
#>
function Test-UserExists
{
[OutputType([System.Boolean])]
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[System.String]
$Username
)
if (Test-IsNanoServer)
{
return Test-UserExistsOnNanoServer @PSBoundParameters
}
else
{
return Test-UserExistsOnFullSKU @PSBoundParameters
}
}
<#
.SYNOPSIS
Tests if a user with the given username exists on a full server.
.PARAMETER Username
The username of the user.
#>
function Test-UserExistsOnFullSKU
{
[OutputType([System.Boolean])]
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[System.String]
$Username
)
$principalContext = New-Object -TypeName 'System.DirectoryServices.AccountManagement.PrincipalContext' `
-ArgumentList @( [System.DirectoryServices.AccountManagement.ContextType]::Machine )
$user = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($principalContext, $Username)
$userExists = $null -ne $user
$null = $principalContext.Dispose()
return $userExists
}
<#
.SYNOPSIS
Tests if a user with the given username exists on a Nano server.
.PARAMETER Username
The username of the user.
#>
function Test-UserExistsOnNanoServer
{
[OutputType([System.Boolean])]
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[System.String]
$Username
)
$userExists = $true
try
{
$null = Get-LocalUser -Name $Username
}
catch [System.Exception]
{
if ($_.CategoryInfo.ToString().Contains('UserNotFoundException'))
{
$userExists = $false
}
else
{
$_.Exception
}
}
return $userExists
}
<#
.SYNOPSIS
Creates a user account.
.PARAMETER Credential
The credential containing the user's username and password.
#>
function New-User
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential
)
if (Test-UserExists -Username $Credential.UserName)
{
throw "User $($Credential.UserName) already exists."
}
if (Test-IsNanoServer)
{
New-UserOnNanoServer @PSBoundParameters
}
else
{
New-UserOnFullSKU @PSBoundParameters
}
}
<#
.SYNOPSIS
Creates a user on a full server.
.PARAMETER Credential
The credential containing the user's username and password.
#>
function New-UserOnFullSKU
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential
)
$userName = $Credential.UserName
$password = $Credential.GetNetworkCredential().Password
$adsiComputerEntry = [System.DirectoryServices.DirectoryEntry] ("WinNT://$env:computerName")
$adsiUserEntry = $adsiComputerEntry.Create('User', $userName)
$null = $adsiUserEntry.SetPassword($password)
$null = $adsiUserEntry.SetInfo()
}
<#
.SYNOPSIS
Creates a user on a Nano server.
.PARAMETER Credential
The credential containing the user's username and password.
#>
function New-UserOnNanoServer
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential
)
$userName = $Credential.UserName
$securePassword = $Credential.GetNetworkCredential().Password
New-LocalUser -Name $userName -Password $securePassword
}
<#
.SYNOPSIS
Removes a user.
.PARAMETER UserName
The name of the user.
#>
function Remove-User
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[System.String]
$UserName
)
if (-not (Test-UserExists -Username $Username))
{
throw "User $Username does not exist to remove."
}
if (Test-IsNanoServer)
{
Remove-UserOnNanoServer @PSBoundParameters
}
else
{
Remove-UserOnFullSKU @PSBoundParameters
}
}
<#
.SYNOPSIS
Removes a user on a full server.
.PARAMETER UserName
The name of the user.
#>
function Remove-UserOnFullSKU
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[System.String]
$UserName
)
$adsiComputerEntry = [System.DirectoryServices.DirectoryEntry] ("WinNT://$env:computerName")
$null = $adsiComputerEntry.Delete('User', $UserName)
}
<#
.SYNOPSIS
Removes a user on a Nano server.
.PARAMETER UserName
The name of the user.
#>
function Remove-UserOnNanoServer
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[System.String]
$UserName
)
$null = Remove-LocalUser -Name $UserName
}
Export-ModuleMember -Function @( 'New-Group', 'Remove-Group', 'Test-GroupExists', 'New-User', 'Remove-User' )