<#
.Synopsis
 This script will extend the AD schema if needed, create the system management container and set
 permisions on the contanier.

.Description
 This script will extend the AD schema if needed, create the system management container and set
 permisions on the contanier.

 Additional Information:
    - To run this script the user account must have schema and domain admin rights.
    - Include the primary site server and the MP in the command line input for -SiteServers.
    - Create the AD group for SiteServers before running this script.  Add the MP and site server.
    - You can run extadsch.exe from SMSSETUP\BIN\X64 or copy the file and run it from any folder.

.PARAMETER ExtadschPath
 Path to the schema extension file Extadsch.exe

.PARAMETER ADgroup
 Permission to the System Management folder will be granted to this group. Add the MP and site
 server to this group.
 
.Example
Set-SchemaSysMan -ExtadschPath C:\Hold\extadsch.exe -ADgroup "GroupNameGoesHere_SiteServers"

.Notes
 Created on:  09/05/2018
 Created by:  Lynford Heron
 Filename:    Set-SchemaSysMan.ps1
 Version:     1.0

#>

Function Set-SchemaSysMan {

Param
(
    [Parameter(Mandatory = $true)]
    [ValidateNotNullorEmpty()]
    [String]$ExtadschPath,
    [Parameter(Mandatory = $true)]
    [ValidateNotNullorEmpty()]
    [String]$ADgroup
)

If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
        [Security.Principal.WindowsBuiltInRole] "Administrator"))

    {
        Write-Warning "You do not have Administrator rights to run this script!`nPlease re-run this script as an Administrator!"
        Break
    }

Clear-Host
$StartTime = Get-Date

$ADmodule = (Get-module -Name Activedirectory).Name
If($ADmodule){Write-Host "The AD module exist." -ForegroundColor Yellow}
Else { Write-host "The AD module does not exist.  Importing, please wait..." -ForegroundColor Cyan
       Install-WindowsFeature RSAT-AD-PowerShell | Out-Null
     }
Write-host "Importing Active Directory module, please wait..." -ForegroundColor Yellow
Import-Module -Name ActiveDirectory

#Extend schema if needed - Confirm Schema Extension
Write-Host "---------------- Checking if the Schema was updated ------------------" -ForegroundColor Cyan
Try
    {
      $schema = [DirectoryServices.ActiveDirectory.ActiveDirectorySchema]::GetCurrentSchema()
      $SchemaStatus = ($schema.FindClass("mSSMSSite")).Name
    }
Catch
    { $Errmsg = $_.Exception.Message
      Write-Host "SCCM Schema not found - $Errmsg" -ForegroundColor Cyan
    }

If($SchemaStatus -eq "mSSMSSite"){Write-Host "Active Directory Schema was already updated." -ForegroundColor Yellow}
Else
    {  Write-Host "Active Directy (AD) schema was not updated.  Updating the AD Schema.  Please wait..." -ForegroundColor Yellow
       Try {Start-Process -Filepath $ExtadschPath -Wait -ErrorAction Stop}
       Catch { $Errmsg = $_.Exception.Message
               Write-Host "There was a problem extending the SCCM Schema - $Errmsg" -ForegroundColor Cyan
               Break
             }
             Write-Host "Checking if the AD Schema was updated for SCCM" -ForegroundColor Yellow
             $schema = [DirectoryServices.ActiveDirectory.ActiveDirectorySchema]::GetCurrentSchema()
             start-sleep 3
             $schema.RefreshSchema()
             Try{$SchemaStatus = ($schema.FindClass("mSSMSSite")).Name}
             Catch{$Errmsg = $_.Exception.Message;Write-Host "The AD Schema was not updated - $Errmsg" -ForegroundColor Cyan}
             If($SchemaStatus -eq "mSSMSSite"){Write-Host "SCCM Schema was updated successfully." -ForegroundColor yellow}
    }

#Create the system management container
Write-Host "-------------- Creating System Management Container------------"
$DomainDn = ([adsi]"").distinguishedName
$SystemDn = "CN=System," + $DomainDn
$SysContainer = [adsi]"LDAP://$SystemDn"
$SystemManagementContainer = "ad:CN=System Management,CN=System,$DomainDn"

If (!(Test-Path $SystemManagementContainer))
  {
    write-host "Creating System Management container..."
    $SysMgmtContainer = $SysContainer.Create("Container", "CN=System Management")
    $SysMgmtContainer.SetInfo()
    Start-sleep 5
    If (Test-Path $SystemManagementContainer)
      {Write-Host "The System Management container was created successfully" -ForegroundColor Yellow
       Write-Host "Added permissions to the System Management container" -ForegroundColor Yellow
        Try
        {
          $acl = get-acl "ad:CN=System Management,CN=System,$DomainDn"
          $objGroup = Get-ADGroup -filter {Name -like "*SiteServers*"}
          $All = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::SelfAndChildren
          $ace = new-object System.DirectoryServices.ActiveDirectoryAccessRule $objGroup.SID, "GenericAll", "Allow", $All
          $acl.AddAccessRule($ace)
          Set-acl -aclobject $acl "ad:CN=System Management,CN=System,$DomainDn"
        }
        Catch
        {
          $Errmsg = $_.Exception.Message
          Write-Host "There was a problem adding permissions. $Errmsg" -ForegroundColor Cyan
        }
      
      }
    Else {Write-Host "There was a problem creating the System Management container" -ForegroundColor Cyan;break}
  }
Else
  {
    write-host "The System Management container already exists.  Adding permissions." -ForegroundColor Yellow
        Try
        {
          $acl = get-acl "ad:CN=System Management,CN=System,$DomainDn"
          $objGroup = Get-ADGroup -filter {Name -like "*SiteServers*"}
          $All = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::SelfAndChildren
          $ace = new-object System.DirectoryServices.ActiveDirectoryAccessRule $objGroup.SID, "GenericAll", "Allow", $All
          $acl.AddAccessRule($ace)
          Set-acl -aclobject $acl "ad:CN=System Management,CN=System,$DomainDn"
          write-host "All Done..." -ForegroundColor Yellow
        }
        Catch
        {
          $Errmsg = $_.Exception.Message
          Write-Host "There was a problem adding permissions. $Errmsg" -ForegroundColor Cyan
        }
  }

#Report script runtime
$endTime = Get-Date
$TotalRuntime = $endTime - $StartTime
Write-Host "`n End Time:" (Get-Date)
Write-host " Script execution time: $TotalRunTime"
}