Saturday, April 19, 2008

Uploading an EML file to a Mailbox with Exchange Web Services

This is a handy little sample to have in your bag of tricks when you need to exchange messages between disparate messaging systems. This code sample is relatively straight forward in that it uses a file stream to read the byte stream of the EML file which is already in MIME format and then uses a createitem operation and posts the MIME content from the data stream to the Exchange Message Store. The only trick that comes in is when you create the Item in whatever folder you want you need to set the message flags property PR_Message_Flags so the message will appear as a normal Sent Mail in Outlook (otherwise it will just appear as a draft). Also you need to set the flag value so it will also appear as Read (unless you want to have it as unread.)

The sample itself uploads an eml file from the c: drive to a users sent items folder

I’ve put a download copy of the code here the code itself looks like

[warning this code sample may cause global warming if you don't configure your pc to shutdown when not in use thats what those power saving options are for in the control panel]

static void Main(string[] args)
{
String emFileName = @"c:\emchk1.eml";
FileStream fsFileStream = new FileStream(emFileName, FileMode.Open, FileAccess.Read);
byte[] bdBinaryData1 = ReadFully(fsFileStream,fsFileStream.Length);
ExchangeServiceBinding esb = new ExchangeServiceBinding();
esb.Credentials = new NetworkCredential("username", "password", "domain");
esb.Url = @"http://servername/EWS/exchange.asmx";
CreateItemType ciCreateItemRequest = new CreateItemType();
ciCreateItemRequest.MessageDisposition = MessageDispositionType.SaveOnly;
ciCreateItemRequest.MessageDispositionSpecified = true;
ciCreateItemRequest.SavedItemFolderId = new TargetFolderIdType();
DistinguishedFolderIdType sfSenditems = new DistinguishedFolderIdType();
sfSenditems.Id = DistinguishedFolderIdNameType.sentitems;
ciCreateItemRequest.SavedItemFolderId.Item = sfSenditems;
ciCreateItemRequest.Items = new NonEmptyArrayOfAllItemsType();
MessageType wsMessage = new MessageType();
MimeContentType mcMimeContnet = new MimeContentType();
mcMimeContnet.Value = Convert.ToBase64String(bdBinaryData1);
wsMessage.MimeContent = mcMimeContnet;
ExtendedPropertyType sfSentFlag = new ExtendedPropertyType();
PathToExtendedFieldType epExPath = new PathToExtendedFieldType();
epExPath.PropertyTag = "0x0E07";
epExPath.PropertyType = MapiPropertyTypeType.Integer;
sfSentFlag.ExtendedFieldURI = epExPath;
sfSentFlag.Item = "1";
wsMessage.IsRead = true;
wsMessage.ExtendedProperty = new ExtendedPropertyType[1];
wsMessage.ExtendedProperty[0] = sfSentFlag;
ciCreateItemRequest.Items.Items = new ItemType[1];
ciCreateItemRequest.Items.Items[0] = wsMessage;
CreateItemResponseType crCreateItemResponse = esb.CreateItem(ciCreateItemRequest);
if (crCreateItemResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Error)
{
throw new Exception(crCreateItemResponse.ResponseMessages.Items[0].MessageText);
}
else
{
}
}
public static byte[] ReadFully(Stream stream, long initialLength)
{
// ref Function from http://www.yoda.arachsys.com/csharp/readbinary.html
// If we've been passed an unhelpful initial length, just
// use 32K.
if (initialLength < initiallength =" 32768;" buffer =" new" read =" 0;" chunk =" stream.Read(buffer,"> 0)
{
read += chunk;

// If we've reached the end of our buffer, check to see if there's
// any more information
if (read == buffer.Length)
{
int nextByte = stream.ReadByte();

// End of stream? If so, we're done
if (nextByte == -1)
{
return buffer;
}

// Nope. Resize the buffer, put in the byte we've just
// read, and continue
byte[] newBuffer = new byte[buffer.Length * 2];
Array.Copy(buffer, newBuffer, buffer.Length);
newBuffer[read] = (byte)nextByte;
buffer = newBuffer;
read++;
}
}
// Buffer is now too big. Shrink it.
byte[] ret = new byte[read];
Array.Copy(buffer, ret, read);
return ret;
}
}
}

Sunday, April 13, 2008

Exchange Permission and Reverse Permission Powershell Gui version 1 Exchange 2000/3/7

*** There is an update version that include mailbox acls here http://gsexdev.blogspot.com/2008/10/exchange-reverse-permission-audit.html

Exchange mailbox permissions getting you down, don’t know who has access to who’s mailbox, rouge admins or legacy permissions or configurations keeping you up at night, can’t get any more the 500 horses out of the V8 under the bonnet. Okay seriously this is kind of rollup script of a lot of vbs scripts that I’ve posted over the past couple of years in regards to Exchange Mailbox, Send and Receive As, Store and delegated Admin rights. It enumerates permissions from Active Directory firstly from all Mailbox rights, Send and Receive As Rights for Exchange Users and then all Mailbox Store ACL’s and finally from the Root Exchange container in the configuration partition to work out the Rights that have been delegated for Exchange System Manager Delegation wizard. It adds all the permissions to ADO.NET datatables and does some calculations to work out first how many Implicit ACL’s have been added to exchange Mailboxes and how many users have been given send and receive as right to each mailbox. Then via the magic of Hashtables it does a reverse check for both Mailbox and Send as and Receive As rights so you can tell how many mailboxes a certain user account has been granted access to or has send or receive as rights. It then checks store rights so you can see which accounts have been give super user rights on each of your Stores or if your using Exchange 2007 you can see which accounts have been given impersonation rights on each of your stores. The finally check is the Delegated Admin rights check now this was a port of a VBS script I had for Exchange 2000/3 and while some of the permission maps the same in Exchange 2007 its doesn’t map fully the delegated rights in Exchange 2007 hope to fix this in the next version. To get the Mailbox ACL it uses the msexchmailboxsecuritydescriptor AD property which I posted a more simple demonstration type script last week for doing this in Powershell.

After the script has enumerated all the permissions it then builds a Winform and presents a little gui that shows all the totals in a datagrid. To see the individual ACL’s on a particular mailbox you need to select it (then select the type of ACL’s you want to see) and hit the show ACE’s button. The Permission Type box lets you choose between Mailbox, Store or Delegation objects.

This is version 1 hopefully when I have more time I’d like to add a snapshot function in the script so that it saves the permissions everytime it runs. Then whenever you run the script you’ll have the added functionality of being able to compare what permission changes that have been made between the different time points when you have run the script in the past. This turns it into to a pretty powerful little ongoing auditing tool. Also I’d like to add the ability to export to a csv file (I know more blog promises)

Because the script just uses Active directory via ADSI it should work in any Exchange 2000, 2003 or 2007 network from any workstation that has powershell installed.

I’ve put a downloadable version of this script here the script itself looks like

(Warning this script may cause global warming if you really are getting more then 500 horses out of the V8 under the bonnet that and the fact you leave my poor little 4 cylinder Honda in the dust)

[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")

function enumMailboxperms() {
$root = [ADSI]'LDAP://RootDSE'
$dfDefaultRootPath = "LDAP://" + $root.DefaultNamingContext.tostring()
$dfRoot = [ADSI]$dfDefaultRootPath
$gfGALQueryFilter = "(&(&(&(mailnickname=*)(objectCategory=person)(objectClass=user))))"
$dfsearcher = new-object System.DirectoryServices.DirectorySearcher($dfRoot)
$dfsearcher.Filter = $gfGALQueryFilter
$dfsearcher.PropertiesToLoad.Add("msExchMailboxSecurityDescriptor")
$srSearchResult = $dfsearcher.FindAll()
foreach ($emResult in $srSearchResult) {
$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])
"Processing Mailbox - " + $uoUserobject.DisplayName
$mbCount = 0
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()
}
if ($rvMailboxPerms.Containskey($AceName)){
$rvMailboxPerms[$AceName] = [int]$rvMailboxPerms[$AceName] +1
}
else {
$rvMailboxPerms.add($AceName,1)
}
If ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::CreateChild){

[VOID]$rsTable.rows.add($uoUserobject.samaccountname.ToString(),"MailboxRight",$aceName,"Full
Mailbox Access",$ace.AccessControlType)
$mbCount++}
If ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::WriteOwner
-ne 0){
[VOID]$rsTable.rows.add($uoUserobject.samaccountname.ToString(),"MailboxRight",$aceName,"Take
Ownership",$ace.AccessControlType)
$mbCount++}
If ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::WriteDacl){

[VOID]$rsTable.rows.add($uoUserobject.samaccountname.ToString(),"MailboxRight",$aceName,"Modify
User Attributes",$ace.AccessControlType)
$mbCount++}
If ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::ListChildren){

[VOID]$rsTable.rows.add($uoUserobject.samaccountname.ToString(),"MailboxRight",$aceName,"Is
mailbox primary owner of this object",$ace.AccessControlType)
$mbCount++}
If ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::Delete){

[VOID]$rsTable.rows.add($uoUserobject.samaccountname.ToString(),"MailboxRight",$aceName,"Delete
mailbox storage",$ace.AccessControlType)
$mbCount++}
If ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::ReadControl){

[VOID]$rsTable.rows.add($uoUserobject.samaccountname.ToString(),"MailboxRight",$aceName,"Read
permissions",$ace.AccessControlType)
$mbCount++}

}
}
$srCount = 0
$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){
$srCount++
$sidbind = "LDAP://<SID=" + $ace.IdentityReference.Value + ">"
$AceName = $ace.IdentityReference.Value
$aceuser = [ADSI]$sidbind
if ($aceuser.name -ne $null){
$AceName = $aceuser.samaccountname.ToString()
}
[VOID]$rsTable.rows.add($uoUserobject.samaccountname.ToString(),"SendAS-RecieveAS",$AceName,"Send
As",$ace.AccessControlType)
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){
$srCount++
$sidbind = "LDAP://<SID=" + $ace.IdentityReference.Value + ">"
$AceName = $ace.IdentityReference.Value
$aceuser = [ADSI]$sidbind
if ($aceuser.name -ne $null){
$AceName = $aceuser.samaccountname.ToString()
}
[VOID]$rsTable.rows.add($uoUserobject.samaccountname.ToString(),"SendAS-RecieveAS",$AceName,"Recieve
As",$ace.AccessControlType)
if ($rvSendRecieve.Containskey($AceName)){
$rvSendRecieve[$AceName] = [int]$rvSendRecieve[$AceName] +1
}
else {
$rvSendRecieve.add($AceName,1)
}
}
}
}
$nmMailboxPerms.Add($uoUserobject.samaccountname.ToString(),$mbCount)
$nmSendRecieve.Add($uoUserobject.samaccountname.ToString(),$srCount)
}
foreach($key in $nmMailboxPerms.keys){
$rvSRRights = 0
$rvMbRights = 0
if ($rvMailboxPerms.Containskey($key)){
$rvMbRights = $rvMailboxPerms[$key]
}
if ($rvSendRecieve.Containskey($key)){
$rvSRRights = $rvSendRecieve[$key]
}

$rs1Table.Rows.Add($key, $nmMailboxPerms[$key],$nmSendRecieve[$key],$rvMbRights,$rvSRRights)

}
# write-host $nmSendRecieve
$dgDataGrid.datasource = $rs1Table
}

function showACL{
if ($ObjTypeDrop.SelectedItem -eq $null -bor $ObjTypeDrop.SelectedItem -eq
"Mailbox"){

if ($AceTypeDrop.SelectedItem -ne $null){
switch($AceTypeDrop.SelectedItem.ToString()){
"Mailbox-Rights" {$rows = $rsTable.Select("MailboxName = '" +
$rs1Table.DefaultView[$dgDataGrid.CurrentCell.RowIndex][0] + "' And ACLType = 'MailboxRight'")}
"SendAs/ReciveAS-Rights" {$rows = $rsTable.Select("MailboxName = '" +
$rs1Table.DefaultView[$dgDataGrid.CurrentCell.RowIndex][0] + "' And ACLType = 'SendAS-RecieveAS'")}
"Reverse-Mailbox-Rights" {$rows = $rsTable.Select("UserName = '" +
$rs1Table.DefaultView[$dgDataGrid.CurrentCell.RowIndex][0] + "' And ACLType = 'MailboxRight'")}
"Reverse-SendAs/ReciveAS-Rights" {$rows = $rsTable.Select("UserName = '" +
$rs1Table.DefaultView[$dgDataGrid.CurrentCell.RowIndex][0] + "' And ACLType = 'SendAS-RecieveAS'")}
default {$rows = $rsTable.Select("UserName = '" +
$rs1Table.DefaultView[$dgDataGrid.CurrentCell.RowIndex][0] + "' Or MailboxName =
'" + $rs1Table.DefaultView[$dgDataGrid.CurrentCell.RowIndex][0] + "'")}
}
}
else{
$rows = $rsTable.Select("UserName = '" +
$rs1Table.DefaultView[$dgDataGrid.CurrentCell.RowIndex][0] + "' Or MailboxName =
'" + $rs1Table.DefaultView[$dgDataGrid.CurrentCell.RowIndex][0] + "'")
}


$frTable.clear()
foreach ($row in $rows){
$frTable.rows.add($row[0].ToString(),$row[1].ToString(),$row[2].ToString(),$row[3].ToString(),$row[4].ToString())
}
$dgDataGrid1.datasource = $frTable
}
else{
$rows = $msrTable.Select("DistinguishedName='" +
$msr1Table.DefaultView[$dgDataGrid.CurrentCell.RowIndex][3] + "'")
$fr1Table.clear()
foreach ($row in $rows){
$fr1Table.rows.add($row[0].ToString(),$row[1].ToString(),$row[2].ToString(),$row[3].ToString(),$row[4].ToString())
}
$dgDataGrid1.datasource = $fr1Table
}
}

function EnumMailStorePerms(){

$dse = [adsi]("LDAP://Rootdse")
$ERtbl = @{}
$ext = [adsi]("LDAP://cn=Extended-rights,"+$dse.configurationNamingContext)
$ext.psbase.children |% {
if ($ERtbl.containskey($_.rightsGuid.ToString()) -eq $false){
$ERtbl.Add($_.rightsGuid.ToString(),$_.displayName.toString())
}
}

$root = [ADSI]'LDAP://RootDSE'
$cfConfigRootPath = "LDAP://" + $root.configurationNamingContext.tostring()
$cfRoot = [ADSI]$cfConfigRootPath
$sQueryFilter = "(objectCategory=msExchPrivateMDB)"
$dfsearcher = new-object System.DirectoryServices.DirectorySearcher($cfRoot)
$dfsearcher.Filter = $sQueryFilter
$srSearchResult = $dfsearcher.FindAll()
foreach ($emResult in $srSearchResult) {
$soStoreobject = New-Object System.DirectoryServices.directoryentry
$soStoreobject = $emResult.GetDirectoryEntry()
$Storeacls = $soStoreobject.psbase.get_objectSecurity().getAccessRules($true,
$false, [System.Security.Principal.SecurityIdentifier])
foreach($ace in $Storeacls){
if ($ace.IdentityReference.Value -ne "S-1-5-7" -band $ace.IdentityReference.Value
-ne "S-1-1-0" -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()
}
if ($ERtbl.containskey($ace.ObjectType.ToString())){
$rights = $ERtbl[$ace.ObjectType.ToString()] + " " + $ace.ObjectType.ToString()
}
else {
$rights = $ace.activeDirectoryRights.toString()
}
$msrTable.rows.add($soStoreobject.Name.ToString(),$soStoreobject.DistinguishedName.ToString(),$AceName,$rights,$ace.AccessControlType)

}
}
$soServer = [ADSI]("LDAP://" + $soStoreobject.msExchOwningServer)
"Processing MailStore - " + $soServer
$sgStorageGroup = $soStoreobject.psbase.Parent
$msr1Table.rows.add($soServer.Name.ToString(),$sgStorageGroup.Name.ToString(),$soStoreobject.Name.ToString(),$soStoreobject.DistinguishedName.ToString())
}
}

function enDelExchangeRight(){

$root = [ADSI]'LDAP://RootDSE'
$exRootPath = "LDAP://CN=Microsoft Exchange,CN=Services," + $root.configurationNamingContext.tostring()
$exRoot = [ADSI]$exRootPath
$Storeacls = $exRoot.psbase.get_objectSecurity().getAccessRules($true, $false, [System.Security.Principal.SecurityIdentifier])
foreach($ace in $Storeacls){
if ($ace.IdentityReference.Value -ne "S-1-5-7" -band $ace.IdentityReference.Value
-ne "S-1-1-0" -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()
}
switch ($ace.activeDirectoryRights.GetHashCode()){
983551 {$drTable1.rows.add($AceName,"Exchange Full Administration")}
197119 {$drTable1.rows.add($AceName,"Exchange Administration")}
131220 {$drTable1.rows.add($AceName,"Exchange View Only Administrator")}
}


}
}

}


$nmMailboxPerms = @{ }
$nmSendRecieve = @{ }
$rvMailboxPerms = @{ }
$rvSendRecieve = @{ }

$Dataset = New-Object System.Data.DataSet
$rsTable = New-Object System.Data.DataTable
$rsTable.TableName = "Mailbox Rights"
$rsTable.Columns.Add("MailboxName")
$rsTable.Columns.Add("ACLType")
$rsTable.Columns.Add("UserName")
$rsTable.Columns.Add("Rights")
$rsTable.Columns.Add("Status")
$Dataset.tables.add($rsTable)

$Dataveiw = New-Object System.Data.DataView($rsTable1)
$rs1Table = New-Object System.Data.DataTable
$rs1Table.TableName = "ACL-Numbers"
$rs1Table.Columns.Add("AccountName")
$rs1Table.Columns.Add("Mailbox")
$rs1Table.Columns.Add("Send/RecieveAS")
$rs1Table.Columns.Add("Revese_Mailbox")
$rs1Table.Columns.Add("Revese_Send/RecieveAS")
$Dataset.tables.add($rs1Table)

$Dataveiw = New-Object System.Data.DataView($drTable1)
$drTable1 = New-Object System.Data.DataTable
$drTable1.Columns.Add("AccountName")
$drTable1.Columns.Add("DelegatedRights")
$Dataset.tables.add($drTable1)

$frTable = New-Object System.Data.DataTable
$frTable.TableName = "Filtered Mailbox Rights"
$frTable.Columns.Add("MailboxName")
$frTable.Columns.Add("ACLType")
$frTable.Columns.Add("UserName")
$frTable.Columns.Add("Rights")
$frTable.Columns.Add("Status")
$Dataset.tables.add($frTable)


$fr1Table = New-Object System.Data.DataTable
$fr1Table.TableName = "Mailbox Store Rights"
$fr1Table.Columns.Add("MailStore")
$fr1Table.Columns.Add("DistinguishedName")
$fr1Table.Columns.Add("UserName")
$fr1Table.Columns.Add("Rights")
$fr1Table.Columns.Add("Status")
$Dataset.tables.add($fr1Table)

$msrTable = New-Object System.Data.DataTable
$msrTable.TableName = "Filtered Mailbox Store Rights"
$msrTable.Columns.Add("MailStore")
$msrTable.Columns.Add("DistinguishedName")
$msrTable.Columns.Add("UserName")
$msrTable.Columns.Add("Rights")
$msrTable.Columns.Add("Status")
$Dataset.tables.add($msrTable)

$msr1Table = New-Object System.Data.DataTable
$msr1Table.TableName = "Mailbox Store Table"

$msr1Table.Columns.Add("ServerName")
$msr1Table.Columns.Add("StorageGroupName")
$msr1Table.Columns.Add("MailStoreName")
$msr1Table.Columns.Add("DistinguishedName")
$Dataset.tables.add($msr1Table)

$form = new-object System.Windows.Forms.form
$form.Text = "Exchange Permissions Gui"


# Add Show ACE Button

$shaces = new-object System.Windows.Forms.Button
$shaces.Location = new-object System.Drawing.Size(560,19)
$shaces.Size = new-object System.Drawing.Size(90,23)
$shaces.Text = "Show ACE's"
$shaces.Add_Click({showACL})
$form.Controls.Add($shaces)

# Add Object Type Drop Down
$ObjTypeDrop = new-object System.Windows.Forms.ComboBox
$ObjTypeDrop.Location = new-object System.Drawing.Size(160,20)
$ObjTypeDrop.Size = new-object System.Drawing.Size(200,30)
$ObjTypeDrop.Items.Add("Mailbox")
$ObjTypeDrop.Items.Add("Mailbox-Store")
$ObjTypeDrop.Items.Add("Delegated Exchange Admin")
$ObjTypeDrop.Add_SelectedValueChanged({
switch($ObjTypeDrop.SelectedItem.ToString()){
"Mailbox" {$dgDataGrid.datasource = $rs1Table}
"Mailbox-Store" {$dgDataGrid.datasource = $msr1Table}
"Delegated Exchange Admin" {$dgDataGrid.datasource = $drTable1}
}
})
$form.Controls.Add($ObjTypeDrop)

# Add Object Type DropLable
$ObjTypelableBox = new-object System.Windows.Forms.Label
$ObjTypelableBox.Location = new-object System.Drawing.Size(20,20)
$ObjTypelableBox.size = new-object System.Drawing.Size(150,20)
$ObjTypelableBox.Text = "Select Permission Type"
$form.Controls.Add($ObjTypelableBox)

# Add Ace Type DropLable
$AceTypelableBox = new-object System.Windows.Forms.Label
$AceTypelableBox.Location = new-object System.Drawing.Size(660,20)
$AceTypelableBox.size = new-object System.Drawing.Size(80,20)
$AceTypelableBox.Text = "ACE Type"
$form.Controls.Add($AceTypelableBox)

# Add Ace Type Drop Down
$AceTypeDrop = new-object System.Windows.Forms.ComboBox
$AceTypeDrop.Location = new-object System.Drawing.Size(740,20)
$AceTypeDrop.Size = new-object System.Drawing.Size(200,30)
$AceTypeDrop.Items.Add("Mailbox-Rights")
$AceTypeDrop.Items.Add("SendAs/ReciveAS-Rights")
$AceTypeDrop.Items.Add("Reverse-Mailbox-Rights")
$AceTypeDrop.Items.Add("Reverse-SendAs/ReciveAS-Rights")
$form.Controls.Add($AceTypeDrop)

# Select Target Group Box

$OfGbox1 = new-object System.Windows.Forms.GroupBox
$OfGbox1.Location = new-object System.Drawing.Size(12,0)
$OfGbox1.Size = new-object System.Drawing.Size(520,75)
$OfGbox1.Text = "Select Permission Object Type"
$form.Controls.Add($OfGbox1)

# DACL Content Group Box

$OfGbox = new-object System.Windows.Forms.GroupBox
$OfGbox.Location = new-object System.Drawing.Size(550,0)
$OfGbox.Size = new-object System.Drawing.Size(450,75)
$OfGbox.Text = "Show DACL Contents"
$form.Controls.Add($OfGbox)

# Add DataGrid View

$dgDataGrid = new-object System.windows.forms.DataGridView
$dgDataGrid.Location = new-object System.Drawing.Size(10,80)
$dgDataGrid.size = new-object System.Drawing.Size(520,500)
$dgDataGrid.AutoSizeRowsMode = "AllHeaders"
$form.Controls.Add($dgDataGrid)

$dgDataGrid1 = new-object System.windows.forms.DataGridView
$dgDataGrid1.Location = new-object System.Drawing.Size(550,80)
$dgDataGrid1.size = new-object System.Drawing.Size(450,500)
$dgDataGrid1.AutoSizeRowsMode = "AllHeaders"
$form.Controls.Add($dgDataGrid1)


enumMailboxperms
EnumMailStorePerms
enDelExchangeRight

$form.topmost = $true
$form.Add_Shown({$form.Activate()})
$form.ShowDialog()

Sunday, April 06, 2008

Showing Mailbox Rights and Send-as/Receive As rights in Powershell Exchange 2000/3/7

I’ve been working on some permissions scripts in the past couple of weeks and thought I’d post a powershell port of some VBS code from this http://msdn2.microsoft.com/en-us/library/ms992469(EXCHG.65).aspx msdn article. I’ve use this code before in a variety of scripts to read permissions from the Exchange Mailbox DACL via the msexchmailboxsecuritydescriptor AD property. Of course one should never try to set mailbox rights using this property as per http://support.microsoft.com/kb/310866/ so make sure you always treat it as read only. So what I’ve done is put together a quick sample that uses the new ActiveDirectorySecurity class in .NET 2.0 to basically load the DACL from the bytearray representation of the DACL that’s stored in this property. Also I’ve included some code to retrieve the Send-AS and Receive-AS rights from the AD object's DACL.

The code only looks at the Implicitly set ACE's and not the Inherited ACE’s (this could be easily changed) it queries ever mailbox in the domain it is executed in and outputs any explicitly set Mailbox ACE’s and Send-as/Receive-as ACE's out to the cmdline. On Exchange 2007 you could do the same thing in the Exchange Management Shell a lot easier using the get-mailboxpermission and get-adpermission.

I’ve put a download of the code here the script itself looks like.

[warning this script could cause global warming if drive when you should walk somewhere]

$root = [ADSI]'LDAP://RootDSE'
$dfDefaultRootPath = "LDAP://" + $root.DefaultNamingContext.tostring()
$dfRoot = [ADSI]$dfDefaultRootPath
$gfGALQueryFilter = "(&(&(&(mailnickname=*)(objectCategory=person)(objectClass=user))))"
$dfsearcher = new-object System.DirectoryServices.DirectorySearcher($dfRoot)
$dfsearcher.Filter = $gfGALQueryFilter
$dfsearcher.PropertiesToLoad.Add("msExchMailboxSecurityDescriptor")
$srSearchResult = $dfsearcher.FindAll()
foreach ($emResult in $srSearchResult) {
$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])
"Mailbox - " + $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
}
" ACE UserName : " + $AceName
""
If ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::CreateChild){

" Full Mailbox Access"}
If ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::WriteOwner
-ne 0){
" Take Ownership"}
If ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::WriteDacl){

" Modify User Attributes"}
If ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::ListChildren){

" Is mailbox primary owner of this object"}
If ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::Delete){

" Delete mailbox storage"}
If ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::ReadControl){

" Read permissions"}

}
}
$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
}
""
" ACE UserName : " + $AceName
" Send As Rights"
}

}
}
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
}
""
" ACE UserName : " + $AceName
" Recieve As Rights"
}
}
}
}