Monthly Archives: September 2017

How To: Powershell Get Local Administrators and Active Directory Nested Groups – SOX

For the past few years, I’ve been tasked with ensuring that our in-scope servers for Sarbanes-Oxley (SOX) have the correct users and groups in them. Before we would have to screen shot the members of the local admins and all the groups that are in the local admins. I decided to take the time to create a script that gets the local admins of the server and write the output to a transcript file.

Script to get Server Local Administrators:

I named the script Get-ServerLocalAdministrators:

Get-ServerLocalAdministrators.ps1 -domain domain -computername computername

The steps the PowerShell script goes through are:

  • Get domain and server
  • Import PowerShell Modules
  • Get Date and Time
  • Get the working directory
  • Convert the domain and computername to upper and lower for pattern matches
  • Start the transcript in the current directory and use some variables for naming the transcript
  • Get the server’s local administrators object using Get-WmiObject and a where cause for the group component
  • Get the members of the local admins and determine if it’s a user or group.
  • If user, put it in the transcript and tag the user as uer
  • If Group, put the group in a variable to loop through later
  • In the transcript, I’m doing a Write-Host to tag each group. If the group has a sub group, (nested group), then put that in another variable to loop through that as well

Since we have Group Memebers that are cross domain, I had to include the -Server paramater get the object’s distinguished Name and use that for -Server.
The only line you have to change in this script (because I was lazy) is to change line 32 to your domain. So, if your server FQDN is server.subdomain.domain.com you would call this “Domain.com” if it was simply “server.domain.com” then you would call this “com”.

[CmdletBinding()]
Param(
    [Parameter(Mandatory=$True,Position=1)]
        [string]$domain,
    [Parameter(Mandatory=$True,Position=2)]
        [string]$computername
    )

# Importing Modules
if (! @(get-module -name ActiveDirectory).count) 
{
	import-module ActiveDirectory
}

if (! @(get-module -name Microsoft.Powershell.Host).count) 
{
	import-module Microsoft.Powershell.Host
}

if (! @(get-module -name Microsoft.WSMan.Management).count) 
{
	import-module Microsoft.WSMan.Management
}

# Variables
$TimeStamp = get-date -Format yyyyMMddHHmmss
$workingDirectory = (Resolve-Path .\).Path
$ComputerNameLower = $computername.ToLower()
$DomainLower = $domain.ToLower()
$ComputerNameUpper = $computername.ToUpper()
$DomainUpper = $domain.ToUpper()
$parentDomain = "domain.com"
[string]$strcomputer = $computername

Start-Transcript -Path $workingDirectory\AREA6_$DomainUpper.$ComputerNameUpper.$TimeStamp.txt -force

# Getting the Local Admins Group
$admins = Get-WmiObject win32_groupuser –computer "$computername.$domain.$parentDomain"
$admins = $admins | where {$_.groupcomponent –like '*"Administrators"'} 
[array]$DomainGroups = @()
[array]$IsGroup = @()

Write-Host "----------------------------------------------------------------"
Write-Host $computername "Local Administrators"
Write-Host "----------------------------------------------------------------"

# Getting Members of Local Admins
$admins | ForEach-Object {  
    $_.partcomponent –match "Win32_(.+).+Domain\=(.+)\,Name\=(.+)$" > $nul  
    $matches[2].trim('"') + "\" + $matches[3].trim('"') + " Type: " + $matches[1]
    # Finding if Local Administrator member is a Domain Group and adding it to $DomainGroups
    $String = 'Win32_Group.Domain="'+$DomainUpper+'"'
    if ($matches[0].Contains($string)){
        $DomainGroups += ($matches[3].trim('"'))
        }
    }

# Looping through all the Domain Groups in the Local Admins and getting their members
foreach ($DomainGroup in $DomainGroups){
    Write-Host "----------------------------------------------------------------"
    Write-Host "$DomainGroup"
    Write-Host "----------------------------------------------------------------"
    $Members = Get-ADGroupMember $DomainGroup -server "$DomainLower.$parentDomain"
    # If a group member is another group write it to $IsGroup so we can get them later
    foreach ($member in $members){
        If ($member.objectclass -eq "user"){
            Write-host ($member.name)" Type:"($member.objectClass)
            }
        elseif ($member.objectclass -eq "group" -And $IsGroup -notcontains $member){
            Write-Host ($member.name)" Type:"($member.objectClass)
            $IsGroup += $member
            }
        elseif($member.objectclass -eq "group" -And $IsGroup -contains $member){
            }
        }
    }
# As stated above, getting the members of nested groups
foreach ($item in $IsGroup){
    Write-Host "----------------------------------------------------------------"
    Write-Host $item.name
    Write-Host "----------------------------------------------------------------"
    $DN = $item.distinguishedName
    $objectDomain = ((($DN -replace "(.*?)DC=(.*)",'$2') -replace "DC=","") -replace ",",".")
    $members = Get-ADGroupMember $item -server $objectDomain
    foreach ($member in $members){
        write-host $member.name" Type:"$member.objectClass
        }
    }

Stop-Transcript

Limitations: This script only loops through to levels of Active Directory groups on the server. So, if you have nested groups more than that, it won’t continue deeper. I’m going to rewrite this to do full recursion in a function so you can look for that post in the future.

Adding Folder Permissions to IIS_IUSRS via Powershell

For you scripting guys that want to automate everything, For website deployments, you can modify your permissions using the NTFSSecurity Module. This is a simple way to modify ACL’s with powershell. Much easier to use the NTFSSecurity module…

First download the module from here: https://ntfssecurity.codeplex.com/

I would put it in your modules directory on the server. Then import the module with Get-Module -ListAvailable and Import-Module NTFSSecurity.

Now, on to the simple and easy code:

Add-NTFSAccess -Path 'C:\SomeFolder\SubFolder' -Account BUILTIN\IIS_IUSRS -AccessRights Read

You can also use the following AccessRights. Actually, you should be able to get any name as the parameter but these are the most common:
Modify
Read

Also, as a note, IIS_IUSRS is a special internal group that you shouldn’t/can’t prefix with the computer or domain name.

For the Network Service or IUSR, you have to use “NT AUTHORITY\NETWORK SERVICE” OR “NT AUTHORITY\IUSR”

Install / Setup Docker on Windows Server 2016

I’ve been working on installing Docker on Server 2016. Here are the steps I’ve followed and some issues I ran into:

First, you have to have Windows Server 2016.

Run Powershell as Administrator (Right click on PowerShell and RunAs Administrator) – yes, you also have to be a local administrator of the box.

Commands in order:

Install-PackageProvider containerimage -Force

Then you want to see what operating system container images are available:

This step wasn’t in the instructions I was following but is necessary and was raised on the GitHub site as well. The server will reboot after the below command is executed. After it reboots, you need to run the command again. Ugh. I thought it was done and tried to install Windows Server Core and it failed after about 30 minutes.

This is installing and then enabling the Docker Container feature on Windows

Enable-WindowsOptionalFeature -Online -FeatureName Containers

As stated above, run the command again. Once done, it will actually tell you that it’s Online and True:

Install Windows Server Core Container Image

Install the WindowsServerCore Container Image by typing the following command below. This does take a while as it downloads Windows Server Core Container Image:

Install-ContainerImage -Name WindowsServerCore

I went to have a bite to eat, took a nap, Surfed Reddit for a while, went to the bathroom and then it was done!

You can check if the image was downloaded by running looking in the directory:

ls c:\programdata\Microsoft\windows\images

The output should look like this:

 

Now we’re going to install Docker in Windows Server 2016

First, you want to download the Update-ContainerHost.ps1 powershell script. Here is the command:

Invoke-WebRequest https://aka.ms/tp5/Update-Container-Host -Outfile Update-ContainerHost.ps1

Run the command. I actually ran this to download the script while the above install of the Windows Server Core was running:

To be continued…