WindowsPowerShell [Get-Acl / Set-Acl]

So might have guessed with my previous transport post that now I wanted to automated the moving of the logs and database to another drive.

It is nice and simple, you can create a folder on the new drive and change the paths in the EdgeTransport.exe.config and by using Set-TransportServer.

BUT I discovered that some of the folders have specific permissions, mainly for the NetworkService.

So what to do?

Well you can use Get-Acl and the acl list from the source folder, and you can then apply that to the new destination and it works like a dream, except for two gotchas.

1) You can’t have the Network Service as the owner of a folder

2) You need to remove all the permissions on the destination folder and then add the new ones.

 

#1 was quite simple, basically to set the owner of the source folder (oldpath) to be the administrators group and then take a snap shot of the acls and transfer them:

$tmpACL = Get-Acl $OldPath

IF ($tmpACL.owner -MATCH “NT Authority”)
{
#You can’t have any NT Authority groups as an owner.
#replace with administrators
#Reset the Owner and get the permission again
[System.Security.Principal.NTAccount]$newOwner=”Administrators”
$var=get-item $Oldpath
$acl=$var.GetAccessControl()
$acl.SetOwner($NewOwner)
$var.SetAccessControl($acl)
$tmpACL = Get-Acl $OldPath
}

#2 was a challenge.  I was going round and round in circle as I couldn’t remove the premissions on the newfolder.  Then then penny dropped, they are inherited from the folder above, so you need to remove the inheritance.

#Remove inheritance from the folder so you can remove the ACLs
$newAcl.SetAccessRuleProtection($true,$false)
Set-Acl -AclObject $tmpACL -Path $NewPath
$NewAcl = Get-acl $NewPath

And that was it .. cool!

So I created this function.  To use it pass the following:

DoNewFolder -old  -new  -makefldr 1

Enjoy and let me know what you think

 

Function doNewFolder($OldPath,$NewPath, $makefldr)
#Get original ACL and put it on new path
#Create the new folder
{

$makefldr=1 #0=No, 1=Yes

## Parse paramaters (specified as “-paramname paramvalue”)
for($i = 0; $i -lt $args.Length; $i++)
{
switch ($args[$i])
{
“-makefldr”
{
If ($args[$i+1]) {$makefldr = $args[$i+1] ; $i++}
}
“-Old”
{
If ($args[$i+1]) {$OldPath = $args[$i+1] ; $i++}
}
“-new” {
if ($args[$i+1]) {$NewPath = $args[$i+1] ; $i++}
}
}
}

IF ($doDebug) {write-Host $OldPath}
IF ($doDebug) {write-Host $NewPath}
IF ($doDebug) {write-Host $makeFldr}

#Test the OldPath to make sure it actually exists
$tmpErr = “Nothing”
$tmpErr = get-item $oldPath -ErrorAction SilentlyContinue
if ($tmpErr -eq $Null)
{
If ($makefldr = 1) #create folder for newPath of its equal to 1
{
Write-Host “Creating ” $Oldpath
MD $Oldpath -ErrorAction SilentlyContinue | out-Null
}
}

If ($makefldr = 1) #create folder for newPath of its equal to 1
{
Write-Host “C
reating ” $Newpath
MD $Newpath | out-Null
}

$tmpACL = Get-Acl $OldPath

IF ($tmpACL.owner -MATCH “NT Authority”)
{
#You can’t have any NT Authority groups as an owner.
#replace with administrators
#Reset the Owner and get the permission again
[System.Security.Principal.NTAccount]$newOwner=”Administrators”
$var=get-item $Oldpath
$acl=$var.GetAccessControl()
$acl.SetOwner($NewOwner)
$var.SetAccessControl($acl)
$tmpACL = Get-Acl $OldPath
}

#Get the ACLs for the new path
$NewAcl = Get-acl $NewPath

#Remove inheritance from the folder so you can remove the ACLs
$newAcl.SetAccessRuleProtection($true,$false)
Set-Acl -AclObject $tmpACL -Path $NewPath
$NewAcl = Get-acl $NewPath

#Loop the existing ACLs on the NewFolder and remove them
$tmpcnt = $newacl.access.count
for ($i = 0; $i -lt $tmpcnt; $i ++)
{
$NewAcl.RemoveAccessRule($Newacl.Access[0])
}

#Add SDDL from the old path
$NewAcl.SetSecurityDescriptorSddlForm($tmpACL.SDDL)

$tmpAclAccessCount = 0
$tmpAclAccessCount = $tmpACL.Access.count

#Loop the Access Rules from the old path and add them to the new one
for ($i=0; $i -lt $tmpAclAccessCount; $i++)
{
$NewAcl.SetAccessRule($tmpAcl.Access[$i])
}

Set-Acl -AclObject $tmpACL -Path $NewPath
}

Exchange 2007 Server Roles

So we all know that you run Get-ExchangeServer it will list all the Exchange servers you have the roles that have installed on them.

This cool, but it you want to anything clever, you may think you need to parse the ServerRole value to find the role.

Well I discovered this.  The ServerRole value actually has a Value__ (that is 2x underscore suffix) that give you what looks like a bitmask for the ServerRoles.  How cool is that.

Get Server Roles for the current Server
$server = hostname
$serverroles = get-exchangeserver -identity $server
$RoleVar = $serverroles.ServerRole.Value__

2 #MBX Role
4 #CAS Role
6 #MBX & CAS
32 #HUB Role
34 #MBX & HUB
36 #HUB & CAS
38 #MBX & CAS & HUB
64 #EDG Role

So does anyone have a UM server isntalled so I can complete the bitmask map above?

Exchange 2007 Transport Server

So here I am playing with my test lab.  I installed ForeFront my my Hub and Edge transport servers and I started to get these in the application event log:

Event Type:    Warning
Event Source:    MSExchangeTransport
Event Category:    ResourceManager
Event ID:    15002
Description:
The resource pressure is constant at High. Statistics:
Queue database and disk space (“C:Program FilesMicrosoftExchange ServerTransportRolesdataQueuemail.que”) = 59% [High] [Normal=55% MediumHigh=57% High=59%]
Queue database logging disk space (“C:Program FilesMicrosoftExchange ServerTransportRolesdataQueue”) = 59% [Normal] [Normal=91% MediumHigh=93% High=95%]
Version buckets = 1 [Normal] [Normal=40 MediumHigh=60 High=100]
Private bytes = 40% [Normal] [Normal=71% MediumHigh=73% High=75%]
Physical memory load = 69% [limit is 94% to start dehydrating messages.]
Inbound mail submission from other Hub Transport servers, the Internet, the Pickup directory, the Replay directory, and the Mailbox server, if it is on a Hub Transport server, has stopped.
Loading of e-mail from the queuing database, if available, continues.

And when I telneted to the server I would get this:

452 4.3.1 Insufficient system resources

… good ole back pressure! So, what to do?  Well I slapped another disk in and now I need to move the paths to my new G drive.  I thought, I know, run Get-TransportServer, find the paths and just change them!

Typically the folder structure under TransPortRules looks like this:

These are changed in EdgeTransport.exe.config:
-data
–IpFilter <-IPFilterDatabasePath + IPFilterDatabaseLoggingPath
–Queue <-QueueDatabasePath + QueueDatabaseLoggingPath
–Temp <-TemporaryStoragePath

These are change by using Set-TransportServer
-Logs
–Connectivity <-ConnectivityLogPath ** Sometimes this does exist!?!
–MessageTracking <-MessageTrackingLogPath
–ProtocolLog
—SmtpReceive <-ReceiveProtocolLogPath
—SmtpSend <-SendProtocolLogPath
–Routing <-RoutingTableLogPath
–PipelineTracing <-PipelineTracingPath
-Pickup <-PickupDirectoryPath
-Replay <-ReplayDirectoryPath
-Shared

As I found out some of the folders may not exist, but they can still be changed using Set-TransportServer

Err no, you have one more step, as this doesn’t move the mail.que file.  You actually have to update EdgeTransport.exe.config.  When you open it up, you need to change the following lines

Oh by the way, you need to stop the MsExchangeTransport first before you can do this.