Jump to content


TechGuy83

Exchange 2007 Permission Audit

Recommended Posts

I have the code for the permission audit nearly working. I am using powershell with ewsutil.dll.

 

The code drags user objects from AD and then looks at their mailbox, recursive search through all folders and outputs to a csv file anything non default, for example inbox read rights etc.

 

However the code is failing on one chunk of code for some mailboxes and not others.

 

$fldarry = new-object EWSUtil.EWS.BaseFolderIdType[] 1
$dTypeFld = new-object EWSUtil.EWS.DistinguishedFolderIdType
$dTypeFld.Id = [EWSUtil.EWS.DistinguishedFolderIdNameType]::msgfolderroot
$mbMailbox = new-object EWSUtil.EWS.EmailAddressType
$mbMailbox.EmailAddress = $mbMailboxEmail
$dTypeFld.Mailbox = $mbMailbox
$fldarry[0] = $dTypeFld

$FolderList = $ewc.GetAllMailboxFolders($fldarry)
$fldarry1 = new-object EWSUtil.EWS.BaseFolderIdType[] $FolderList.Count
for ($fcint=0;$fcint -lt $FolderList.Count;$fcint++){
$fldarry1[$fcint] = $FolderList[$fcint].FolderId
}
$Folders = $ewc.GetFolder($fldarry1)
If ($Folders.Count -ne 0) {
ForEach ($Folder in $Folders) {

 

Above is the section of code that fails, on the line where $fldarry1 is created below the for, I get on some mailboxes the following error.

 

Exception calling "GetFolder" with "1" argument(s): "The request failed schema
validation: The element 'FolderIds' in namespace 'http://schemas.microsoft.com/
exchange/services/2006/messages' has incomplete content. List of possible eleme
nts expected: 'FolderId, DistinguishedFolderId' in namespace 'http://schemas.mi
crosoft.com/exchange/services/2006/types'."
At #############:175 char:26
+ $Folders = $ewc.GetFolder <<<< ($fldarry1)
+ CategoryInfo		  : NotSpecified: ( [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException

 

Any help would be appreciated. Thanks.

Share this post


Link to post
Share on other sites

Hi,

 

I have an 2007 server where I can test the code and see what I can find out, can you maybe post or send me the full code.

 

What version of EWS API are you using? The version I did find was this one; Web Services Managed API 1.2.1

http://www.microsoft.com/en-us/download/details.aspx?id=30141

Share this post


Link to post
Share on other sites

Ok here you go:

 

[void][Reflection.Assembly]::LoadFile("c:\temp\EWSUtil.dll")

#######################################################################################
## FUNCTION enumMailBoxPerms
#######################################################################################
function enumMailboxperms() {
param ($user)
$root = [ADSI]'LDAP://RootDSE'
$dfDefaultRootPath = "LDAP://OU=Users," + $root.DefaultNamingContext.tostring()
write-host Searching
write-host $dfDefaultRootPath
write-host for mailboxes
$dfRoot = [ADSI]$dfDefaultRootPath
If (!$user) {
$gfGALQueryFilter =  "(&(mailnickname=*)(objectCategory=person)(objectClass=user))"
}
Else {
 $gfGALQueryFilter =  "(&(mailnickname=$user)(objectCategory=person)(objectClass=user))"
}
$dfsearcher = new-object System.DirectoryServices.DirectorySearcher($dfRoot)
$dfsearcher.PageSize = 10000
$dfsearcher.Filter = $gfGALQueryFilter
$dfsearcher.PropertiesToLoad.Add("msExchMailboxSecurityDescriptor")
$dfsearcher.PropertiesToLoad.Add("public-delegates")
$dfsearcher.PropertiesToLoad.Add("public-delegates-bl")
$srSearchResult = $dfsearcher.FindAll()
$i = 0
$ec=0
foreach ($emResult in $srSearchResult) {
if($i -lt 10000) {
$rsTable.clear()
$dsEmail=""
$uoUserobject = New-Object System.DirectoryServices.directoryentry
$uoUserobject = $emResult.GetDirectoryEntry()
$emProps = $emResult.Properties
[byte[]]$DaclByte = $emProps["msexchmailboxsecuritydescriptor"][0]
$adDACL = new-object System.DirectoryServices.ActiveDirectorySecurity
$adDACL.SetSecurityDescriptorBinaryForm($DaclByte)
$mbRightsacls =$adDACL.GetAccessRules($true, $false, [system.Security.Principal.SecurityIdentifier])
   write-host
write-host Processing - $uoUserobject.samaccountname.ToString() ($uoUserobject.DisplayName)
 foreach ($ace in $mbRightsacls){
           if($ace.IdentityReference.Value -ne "S-1-5-10" -band $ace.IdentityReference.Value -ne "S-1-5-18" -band $ace.IsInherited -ne $true){ 
    $sidbind = "LDAP://<SID=" + $ace.IdentityReference.Value + ">"
    $AceName = $ace.IdentityReference.Value
     $aceuser = [ADSI]$sidbind
    if ($aceuser.name -ne $null){
     $AceName = $aceuser.samaccountname.ToString()
                       $AceDisplayName = $aceuser.DisplayName.ToString()
     #added extra coloumn email address to show mailbox email and username
     $mbMailboxEmail = $uoUserobject.mail.ToString()
    }

    if ($AceName -ne $uoUserobject.samaccountname.ToString()) {
     If ($ace.ActiveDirectoryRights -band [system.DirectoryServices.ActiveDirectoryRights]::CreateChild){
      [VOID]$rsTable.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,"Mailbox Root",$aceName,"Full Mailbox Access",$ace.AccessControlType,$AceDisplayName)
      [VOID]$rsTableCSV.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,"Mailbox Root",$aceName,"Full Mailbox Access",$ace.AccessControlType,$AceDisplayName)
     }    
     If ($ace.ActiveDirectoryRights -band [system.DirectoryServices.ActiveDirectoryRights]::WriteOwner -ne 0){
      [VOID]$rsTable.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,"Mailbox Root",$aceName,"Take Ownership",$ace.AccessControlType,$AceDisplayName)
      [VOID]$rsTableCSV.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,"Mailbox Root",$aceName,"Take Ownership",$ace.AccessControlType,$AceDisplayName)
     }
      If ($ace.ActiveDirectoryRights -band [system.DirectoryServices.ActiveDirectoryRights]::WriteDacl){
      [VOID]$rsTable.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,"Mailbox Root",$aceName,"Modify User Attributes",$ace.AccessControlType,$AceDisplayName)
      [VOID]$rsTableCSV.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,"Mailbox Root",$aceName,"Modify User Attributes",$ace.AccessControlType,$AceDisplayName)
     }
      If ($ace.ActiveDirectoryRights -band [system.DirectoryServices.ActiveDirectoryRights]::ListChildren){
      [VOID]$rsTable.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,"Mailbox Root",$aceName,"Is mailbox primary owner of this object",$aceuser.AccessControlType,$AceDisplayName)
      [VOID]$rsTableCSV.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,"Mailbox Root",$aceName,"Is mailbox primary owner of this object",$aceuser.AccessControlType,$AceDisplayName)
     } 
     If ($ace.ActiveDirectoryRights -band [system.DirectoryServices.ActiveDirectoryRights]::Delete){
      [VOID]$rsTable.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,"Mailbox Root",$aceName,"Delete mailbox storage",$ace.AccessControlType,$AceDisplayName)
      [VOID]$rsTableCSV.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,"Mailbox Root",$aceName,"Delete mailbox storage",$ace.AccessControlType,$AceDisplayName)
     }
     If ($ace.ActiveDirectoryRights -band [system.DirectoryServices.ActiveDirectoryRights]::ReadControl){
      [VOID]$rsTable.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,"Mailbox Root",$aceName,"Read permissions",$ace.AccessControlType,$AceDisplayName)
      [VOID]$rsTableCSV.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,"Mailbox Root",$aceName,"Read permissions",$ace.AccessControlType,$AceDisplayName)
     }
    }
  }
 }
 $Sendasacls = $uoUserobject.psbase.get_objectSecurity().getAccessRules($true, $false, [system.Security.Principal.SecurityIdentifier])|? {$_.ObjectType -eq 'ab721a54-1e2f-11d0-9819-00aa0040529b'}
 $Recieveasacls = $uoUserobject.psbase.get_objectSecurity().getAccessRules($true, $false, [system.Security.Principal.SecurityIdentifier])|? {$_.ObjectType -eq 'ab721a56-1e2f-11d0-9819-00aa0040529b'}
 if ($Sendasacls -ne $null){
  foreach ($ace in $Sendasacls)
  {
   if($ace.IdentityReference.Value -ne "S-1-5-10" -band $ace.IdentityReference.Value -ne "S-1-5-18" -band $ace.IsInherited -ne $true){
    $sidbind = "LDAP://<SID=" + $ace.IdentityReference.Value + ">"
    $AceName = $ace.IdentityReference.Value
    $aceuser = [ADSI]$sidbind
    if ($aceuser.name -ne $null){
     $AceName = $aceuser.samaccountname.ToString()
                       $AceDisplayName = $aceuser.DisplayName.ToString()
    }
    if ($AceName -ne $uoUserobject.samaccountname.ToString()) {
     [VOID]$rsTable.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,"Mailbox Root",$AceName,"Send As",$ace.AccessControlType,$AceDisplayName)
     [VOID]$rsTableCSV.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,"Mailbox Root",$AceName,"Send As",$ace.AccessControlType,$AceDisplayName)
     if ($rvSendRecieve.Containskey($AceName)){
      $rvSendRecieve[$AceName] = [int]$rvSendRecieve[$AceName] +1  
     }
     else {
      $rvSendRecieve.add($AceName,1)
     }
    }
   }

  }
 }
 if ($Recieveasacls -ne $null){
  foreach ($ace in $Recieveasacls)
  {
   if($ace.IdentityReference.Value -ne "S-1-5-10" -band $ace.IdentityReference.Value -ne "S-1-5-18" -band $ace.IsInherited -ne $true){
    $sidbind = "LDAP://<SID=" + $ace.IdentityReference.Value + ">"
    $AceName = $ace.IdentityReference.Value
    $aceuser = [ADSI]$sidbind
    if ($aceuser.name -ne $null){
     $AceName = $aceuser.samaccountname.ToString()
                       $AceDisplayName = $aceuser.DisplayName.ToString()
    }
    if ($AceName -ne $uoUserobject.samaccountname.ToString()) {
     [VOID]$rsTable.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,"Mailbox Root",$AceName,"Recieve As",$ace.AccessControlType,$AceDisplayName)
     [VOID]$rsTableCSV.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,"Mailbox Root",$AceName,"Recieve As",$ace.AccessControlType,$AceDisplayName)
     if ($rvSendRecieve.Containskey($AceName)){
      $rvSendRecieve[$AceName] = [int]$rvSendRecieve[$AceName] +1  
     }
     else {
      $rvSendRecieve.add($AceName,1)
     }
    }
   }
  }
 }
 $mbMailboxEmail = $uoUserobject.mail.ToString()
 #write-host "Doing Mailbox Permissions with EWS"
 $useImp = $false
 $ewc = new-object EWSUtil.EWSConnection($mbMailboxEmail,$useImp, "", "", "",$casUrl)
 # $fldarry = new-object EWSUtil.EWS.BaseFolderIdType[] 6
 # for ($fcint=0;$fcint -lt 6;$fcint++){
  # $dTypeFld = new-object EWSUtil.EWS.DistinguishedFolderIdType

  # switch ($fcint){
   # 0 {$dTypeFld.Id = [EWSUtil.EWS.DistinguishedFolderIdNameType]::inbox}
   # 1 {$dTypeFld.Id = [EWSUtil.EWS.DistinguishedFolderIdNameType]::calendar}
   # 2 {$dTypeFld.Id = [EWSUtil.EWS.DistinguishedFolderIdNameType]::contacts}
   # 3 {$dTypeFld.Id = [EWSUtil.EWS.DistinguishedFolderIdNameType]::tasks}
   # 4 {$dTypeFld.Id = [EWSUtil.EWS.DistinguishedFolderIdNameType]::journal}
   # 5 {$dTypeFld.Id = [EWSUtil.EWS.DistinguishedFolderIdNameType]::msgfolderroot}
  # }
  # $mbMailbox = new-object EWSUtil.EWS.EmailAddressType
  # $mbMailbox.EmailAddress = $mbMailboxEmail
  # $dTypeFld.Mailbox = $mbMailbox
  # $fldarry[$fcint] = $dTypeFld
 # }

$fldarry = new-object EWSUtil.EWS.BaseFolderIdType[] 1
$dTypeFld = new-object EWSUtil.EWS.DistinguishedFolderIdType
$dTypeFld.Id = [EWSUtil.EWS.DistinguishedFolderIdNameType]::msgfolderroot
$mbMailbox = new-object EWSUtil.EWS.EmailAddressType
$mbMailbox.EmailAddress = $mbMailboxEmail
$dTypeFld.Mailbox = $mbMailbox
$fldarry[0] = $dTypeFld
$FolderList = $ewc.GetAllMailboxFolders($fldarry)
$fldarry1 = new-object EWSUtil.EWS.BaseFolderIdType[] $FolderList.Count
for ($fcint=0;$fcint -lt $FolderList.Count;$fcint++){
$fldarry1[$fcint] = $FolderList[$fcint].FolderId
}
$Folders = $ewc.GetFolder($fldarry1)
 If ($Folders.Count -ne 0) {
   ForEach ($Folder in $Folders) {

   if ($Folder.GetType() -eq  [EWSUtil.EWS.CalendarFolderType]){
   #write-host "Checking calendar permissions"
    ForEach ($Permissions in $Folder.PermissionSet.CalendarPermissions){
     if ($Permissions.UserId.DistinguishedUserSpecified -eq $false){
      $sidbind = "LDAP://<SID=" + $Permissions.UserId.SID.ToString() + ">"
      $AceName = $ace.IdentityReference.Value
      $aceuser = [ADSI]$sidbind
      if (!((($Folder.DisplayName -eq 'Calendar') -and ($aceuser.samaccountname -eq 'distu All')) -or ($aceuser.samaccountname -eq 'Default') -or ($aceuser.samaccountname -eq $uoUserobject.samaccountname.ToString()))) {
       [VOID]$rsTable.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,$Folder.DisplayName,$aceuser.samaccountname.ToString(),$ewc.enumOutlookRole($Permissions),"Allow",$aceuser.displayname.ToString())
       [VOID]$rsTableCSV.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,$Folder.DisplayName,$aceuser.samaccountname.ToString(),$ewc.enumOutlookRole($Permissions),"Allow",$aceuser.displayname.ToString())
       if ($rvFolderPerms.Containskey($aceuser.samaccountname.ToString())){
        $rvFolderPerms[$aceuser.samaccountname.ToString()] = [int]$rvFolderPerms[$aceuser.samaccountname.ToString()] +1  
       }
       else {
        $rvFolderPerms.add($aceuser.samaccountname.ToString(),1)
       }
      }
     }
     #else{
      #if ($Permissions.UserId.DistinguishedUser -eq [EWSUtil.EWS.DistinguishedUserType]::Default){
       #if ($Permissions.CalendarPermissionLevel -ne [EWSUtil.EWS.CalendarPermissionLevelType]::None){
        # Adding some logic here to try to filter out unwanted data
        #if (!($ewc.enumOutlookRole($Permissions) -eq 'Default')) {
        #[VOID]$rsTable3.rows.add($Folder.DisplayName,"Default",$ewc.enumOutlookRole($Permissions),"Allow")
         #}
        #}
      #}
     #}
    }

   }
   else {
    ForEach ($Permissions in $Folder.PermissionSet.Permissions){
    #write-host "Checking folder permissions"
     #List any folders here you do not want to be listed on the CSV or Email
     #if ($Folder.DisplayName -ne "Top of Information Store"){
      if ($Permissions.UserId.DistinguishedUserSpecified -eq $false){
       $sidbind = "LDAP://<SID=" + $Permissions.UserId.SID.ToString() + ">"
       $AceName = $ace.IdentityReference.Value
       $aceuser = [ADSI]$sidbind
       $test = $aceuser.samaccountname.ToString()
       if (!(($aceuser.samaccountname -eq 'nothim') -or ($aceuser.samaccountname -eq 'nother') -or ($aceuser.samaccountname -eq $uoUserobject.samaccountname.ToString()) -or ($Permissions.PermissionLevel -eq 'None'))) {
        [VOID]$rsTable.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,$Folder.DisplayName,$aceuser.samaccountname.ToString(),$Permissions.PermissionLevel.ToString(),"Allow",$aceuser.displayname.ToString())
        [VOID]$rsTableCSV.rows.add($uoUserobject.samaccountname.ToString(),$mbMailboxEmail,$Folder.DisplayName,$aceuser.samaccountname.ToString(),$Permissions.PermissionLevel.ToString(),"Allow",$aceuser.displayname.ToString())
        if ($rvFolderPerms.Containskey($aceuser.samaccountname.ToString())){
         $rvFolderPerms[$aceuser.samaccountname.ToString()] = [int]$rvFolderPerms[$aceuser.samaccountname.ToString()] +1  
        }
        else {
         $rvFolderPerms.add($aceuser.samaccountname.ToString(),1)
        }
       }
      }
     #}
     #else{
      #if ($Permissions.UserId.DistinguishedUser -eq [EWSUtil.EWS.DistinguishedUserType]::Default){
       #if ($Permissions.PermissionLevel -ne [EWSUtil.EWS.PermissionLevelType]::None){
        #[VOID]$rsTable3.rows.add($Folder.DisplayName,"Default",$Permissions.PermissionLevel.ToString(),"Allow")
        #}
      #}
     #}
    }
   }
  }
 }
 }

 $i++
 #write-host $i
 #emailResults
 $ec++
}
}

#######################################################################################
## END FUNCTION enumMailBoxPerms
#######################################################################################

$Dataset = New-Object System.Data.DataSet
$rsTable = New-Object System.Data.DataTable
[void]$rsTable.TableName = "Mailbox Rights"
[void]$rsTable.Columns.Add("MailboxUsername")
[void]$rsTable.Columns.Add("MailboxEmail")
[void]$rsTable.Columns.Add("FolderName")
[void]$rsTable.Columns.Add("UserName")
[void]$rsTable.Columns.Add("Rights")
[void]$rsTable.Columns.Add("Status")
[void]$rsTable.Columns.Add("DisplayName")
[void]$Dataset.tables.add($rsTable)
$rsTableCSV = New-Object System.Data.DataTable
[void]$rsTableCSV.TableName = "Mailbox Rights"
[void]$rsTableCSV.Columns.Add("MailboxUsername")
[void]$rsTableCSV.Columns.Add("MailboxEmail")
[void]$rsTableCSV.Columns.Add("FolderName")
[void]$rsTableCSV.Columns.Add("UserName")
[void]$rsTableCSV.Columns.Add("Rights")
[void]$rsTableCSV.Columns.Add("Status")
[void]$rsTableCSV.Columns.Add("DisplayName")
[void]$Dataset.tables.add($rsTableCSV)
$process = read-host "Enter a users username [Enter] to report on all"
$nmMailboxPerms = @{ }
$nmSendRecieve = @{ }
$fpFolderPerms = @{ }
$duFolderPerms = @{ }
$rvMailboxPerms = @{ }
$rvSendRecieve = @{ }
$rvFolderPerms = @{ }
$nmDelegatePerms = @{ }
$rvDelegatePerms = @{ }
$nmDefualtPerms = @{ }
enumMailboxperms $process
 if($rsTableCSV.Rows.Count -gt 0) {
          $rsTableCSV | export-csv c:\rsTableCSV.csv -notypeinformation
 }

Share this post


Link to post
Share on other sites

Just had a thought perhaps I am over complicating things, if they do not have permission on the root its not possible then to access the inbox? Am I right in thinking that?

 

Of course calendar can be directly accessed so not sure if it applies to other folders.

 

If its the case then it maybe worth just running audit on the mailbox root and calendar, this runs with no errors.

Share this post


Link to post
Share on other sites

Hi,

I've been trying to find the EWS Managed API 1.0.0 but can't find it..

Do you got it? Maybe you can share it at skydrive etc?

 

Sounds like you aimed your own issue, when i got the API i will be testing this in my lab and give you my result

 

Sorry for the late reply

Share this post


Link to post
Share on other sites

Sorry for my late reply, we went with the basics as outlook will open only the default folders. Recursive permission audit was to unstable. Really appreciate your help.

 

This sent out an email to the users which worked well on the whole, however it did identify accounts that simply couldn't be seen by any other method over than scripting.

 

However if anyone does have a great permission auditing script they use please share, I was less than satisfied with the results from the script I used, nothing terrible but just a few people with accounts that wernt. Listed inoutlook or exchange console.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...