Friday, November 16, 2018

Powershell - lessons learned when trying to document ADSI permissions...

I had a need to document permissions assigned from within ADSI to a configuration container with hundreds / thousands of objects beneath.

Powershell surprisingly treats active directory much like the file system with regards to it's object references when you're looking for access rights information.

What I couldn't find was a good reference for how to recursively report on permissions under Active Directory's configuration area (think MS Exchange).

Below is my first attempt at code to dump all CN / OU permissions. Note that AD pathing is important, and you'll want to edit the $config line to the path you want to report on.

****************************Begin Script******************************************

Import-module activedirectory
$Temp="c:\temp\test.txt"
$config=get-childitem -recurse -path "AD:CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=YourDomain,DC=com" | select -expandproperty DistinguishedName
Foreach ($object in $config)
{
$Path="AD:" + $object
$object >>$Temp
(get-acl $path).Access | Where {$_.IsInherited -eq $FALSE}|select InheritanceType,AccessControlType,IdentityReference,IsInherited >>$Temp
echo " ">>$Temp
}

****************************End Script ********************************************

This code, got the job done, it documented my permissions, but it created a fairly large Txt file which was a bit of a chore to sift through. It can be done better. . .

However, lets talk about what is going on with what we have first. . . If you're following along in the script, the data returned from the $config query is the full path to the AD object we want to query. But we can't just give that path to the "get-acl" command, it won't take it. Instead, we have to pre-pend the "AD:" to the query for get-acl, so a separate variable is used to turn our $config path into a value that get-acl can actually query and report on.

Also note, the data set is trimmed to only return directly assigned permissions. Any "inherited" permissions won't be shown as that makes for a massively sized report.

So I had results, but I wasn't happy with how it was presented, so I thought a bit about how I was getting at the data I wanted, and how it was being expressed . . and I realized something that I feel is very important to understand with powershell . . .

I am using a command in "get-acl" which returns multiple values. I point it at a folder / file / adobject, and it gives me a response that I can further filter to get only the data I want . . but I have to tinker with powershell a bit to do it...in my first code attempt no filtering was being done of the get-acl data, I was just displaying it as powershell would present it . . to a text file.

Here's another attempt at the same task, but filtering the get-acl query into specific values that a report is then built from:

**********************Begin Script****************************************

Import-module activedirectory
$Temp="c:\temp\test.txt"
$DataSet=get-childitem -recurse -path "AD:CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=YourDomain,DC=com" | select -expandproperty DistinguishedName
echo "CN Path;Group;Allow-Deny;Permissions;Inherited">$Temp
Write-host "Gathering permissions data..." -foregroundcolor Green
Foreach ($object in $DataSet)
{
$Path="AD:" + $object
$PermCheck=(get-acl $path).Access | Where {$_.IsInherited -eq $FALSE} | select ActiveDirectoryRights,AccessControlType,IdentityReference,IsInherited
Foreach ($Perm in $PermCheck)
{
$ADR=$perm.activedirectoryrights
$ACT=$perm.accesscontroltype
$IR=$perm.IdentityReference
$II=$perm.isinherited
echo "$object;$IR;$ACT;$ADR;$II">>$Temp
}
}
echo " "
Write-host "Data dump completed, finalizing report..." -foregroundcolor Green
$csv="c:\temp\MSAD-Perms-Config-Exchange.csv"
import-csv $Temp -delimiter ";" | export-csv $csv -NoTypeInformation
$ReportXLSX="c:\temp\MSAD-Perms-Config-Exchange.xlsx"
$vbscript="\\server\networkshare\CSV-Convert\csv_to_excel.vbs"
& $vbscript $csv $reportxlsx
timeout /t 5 /nobreak
echo " "
write-host "Report created" -foregroundcolor Green
echo " "

********************End Script*******************************************

Following along in the code here, I've changed the "get-acl" into a variable, then added a foreach section to make new variables out of each of the specific values I want to see queried from each permission. Then, only those values are "echo'd" to my waiting temp text file. The data sent to the txt file is separated with a ';' for importing with import-csv later in the script. I also referencing some code I've leveraged in the past on my blog in other postings, to convert a CSV file into a pre-formated XLSX file.

The result is a clear break-out of any and all permission assignments for an AD structure. The more I think about this, it feels like it wouldn't take much to convert this same code to reporting on file system permissions. I may test that out in another blog posting . . . ;)

Hope this helps others-

Thursday, September 20, 2018

Powershell - quickly stopping all skype services

For some reason, there's very little out there on a quick way to find and stop all skype services (this is now needed when running skype updates.)

Skype has it's own powershell commandlets for doing a variety of administration for skype systems, in this case we're going to leverage a single line command to get and stop all services:

*****script start*****

get-cswindowsservice | stop-cswindowsservice

*****script end*****

I have seen cases where this will simply hang out because the services themselves are locked up. In those cases, you either need to wait out the service stopping, or force a reboot and try again after your server is back online.