Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 35 additions & 41 deletions Setup/SetupAssist/Checks/UserContext/Test-UserGroupMemberOf.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Licensed under the MIT License.

. $PSScriptRoot\..\..\..\..\Shared\Confirm-Administrator.ps1
. $PSScriptRoot\..\..\..\..\Shared\Get-WellKnownGroupSid.ps1
. $PSScriptRoot\..\New-TestResult.ps1
Function Test-UserGroupMemberOf {
[CmdletBinding()]
Expand All @@ -10,42 +11,6 @@ Function Test-UserGroupMemberOf {
[bool]$PrepareSchemaRequired
)

function GetGroupMatches($whoamiOutput, $groupName) {
$m = @($whoamiOutput | Select-String "(^\w+\\$($groupName))\s+")
if ($m.Count -eq 0) { return $m }
return $m | ForEach-Object {
[PSCustomObject]@{
GroupName = ($_.Matches.Groups[1].Value)
SID = (GetSidFromLine $_.Line)
}
}
}

Function GetSidFromLine ([string]$Line) {
$startIndex = $Line.IndexOf("S-")
return $Line.Substring($startIndex,
$Line.IndexOf(" ", $startIndex) - $startIndex)
}

Function TestGroupResult($WhoamiOutput, $GroupName) {
[array]$g = GetGroupMatches $WhoamiOutput $GroupName
$params = @{
TestName = $GroupName
Details = "Not a member of the $GroupName Group"
}

if ($g.Count -gt 0) {
$params.Details = "$($g.GroupName) $($g.SID)"
New-TestResult @params -Result "Passed"
} elseif ($GroupName -eq "Schema Admins") {
New-TestResult @params -Result "Failed" -ReferenceInfo "User must be in Schema Admins to update Schema which is required."
} elseif ($GroupName -eq "Enterprise Admins") {
New-TestResult @params -Result "Failed" -ReferenceInfo "User must be Enterprise Admins to do PrepareSchema or PrepareAD"
} else {
New-TestResult @params -Result "Failed"
}
}

$whoami = whoami
$whoamiAllOutput = whoami /all
$userSid = ($whoamiAllOutput | Select-String $whoami.Replace("\", "\\")).Line.Replace($whoami, "").Trim()
Expand All @@ -61,15 +26,44 @@ Function Test-UserGroupMemberOf {
New-TestResult @params -Result "Failed"
}

TestGroupResult $whoamiAllOutput "Organization Management"
$groupRequirements = @(
@{
Name = "Organization Management"
Role = "Organization Management"
Reason = "User must be in the Organization Management Group"
}
)

if ($PrepareSchemaRequired) {
TestGroupResult $whoamiAllOutput "Schema Admins"
$groupRequirements += @{
Name = "Schema Admins"
Role = (Get-WellKnownGroupSid "Schema Admins")
Reason = "User must be in Schema Admins to update Schema which is required."
}
}

if ($PrepareAdRequired) {
TestGroupResult $whoamiAllOutput "Domain Admins"
TestGroupResult $whoamiAllOutput "Enterprise Admins"
$groupRequirements += @{
Name = "Enterprise Admins"
Role = (Get-WellKnownGroupSid "Enterprise Admins")
Reason = "User must be Enterprise Admins to do PrepareSchema or PrepareAD."
}

$groupRequirements += @{
Name = "Domain Admins"
Role = (Get-WellKnownGroupSid "Domain Admins")
Reason = "User must be in Domain Admins to do PrepareAD which is required."
}
}
}

$principal = (New-Object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent()))

foreach ($group in $groupRequirements) {
if ($principal.IsInRole($group.Role)) {
$params.Details = "$($group.Name) $($group.Role)"
New-TestResult @params -Result "Passed"
} else {
New-TestResult @params -Result "Failed" -ReferenceInfo $group.Reason
}
}
}
51 changes: 51 additions & 0 deletions Shared/Get-WellKnownGroupSid.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

<#
.SYNOPSIS
Returns the SID of the desired group.
.DESCRIPTION
Long description
.EXAMPLE
PS C:\> Get-WellKnownGroupSid -GroupType "Enterprise Admins"

Returns the SID of the Enterprise Admins group.
.EXAMPLE
PS C:\> Get-WellKnownGroupSid -GroupType "Schema Admins"

Returns the SID of the Schema Admins group.
.EXAMPLE
PS C:\> Get-WellKnownGroupSid -GroupType "Domain Admins"

Returns the SID of the Domain Admins group from the domain that the current computer is in.
#>
function Get-WellKnownGroupSid {
[CmdletBinding()]
[OutputType([System.Security.Principal.SecurityIdentifier])]
param(
[Parameter(Mandatory = $true)]
[ValidateSet("Enterprise Admins", "Schema Admins", "Domain Admins")]
[string]
$GroupType
)

$forest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()

$rootDomainSidBytes = [byte[]] $forest.RootDomain.GetDirectoryEntry().Properties["objectSid"][0]
$rootDomainSid = New-Object System.Security.Principal.SecurityIdentifier($rootDomainSidBytes, 0)

$computerDomainSidBytes = [byte[]] [System.DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain().GetDirectoryEntry().Properties["objectSid"][0]
$computerDomainSid = New-Object System.Security.Principal.SecurityIdentifier($computerDomainSidBytes, 0)

switch ($GroupType) {
"Enterprise Admins" {
return New-Object System.Security.Principal.SecurityIdentifier("${rootDomainSid}-519")
}
"Schema Admins" {
return New-Object System.Security.Principal.SecurityIdentifier("${rootDomainSid}-518")
}
"Domain Admins" {
return New-Object System.Security.Principal.SecurityIdentifier("${computerDomainSid}-512")
}
}
}