Category: Uncategorized

#Error Code List
# 0 No Litigation Hold
# 1 Litigation Hold
#Param must be the first executable line
[CmdletBinding()]
Param(
    [string] $EID = "SamAccountName" #Eid to check for Litigation Hold
 )
#Remove-Variable * -ErrorAction SilentlyContinue; Remove-Module *; $error.Clear(); Clear-Host #You cannot use this with Param
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
try
{
    $Onhold = get-mailbox $EID
    if ($Onhold -eq $null)
    {
        Write-Host "Powershell: No mailbox located for this user!"
        exit 0
    }

    if ($Onhold.LitigationHoldEnabled -eq $false)
    {
        Write-Host "Powershell: This box is NOT on hold!"
        exit 0
    }
    else
    {
        Write-Host "Powershell: This box is on hold!"
        exit 1
    }
}
catch
{
    $_
    $_.Exception.Message
    $_.Exception.ItemName
    Write-Host "Powershell: Exception for " + $EID + "!"
    exit 1
}

A little nifty Powershell script I threw together to move users around as they get promoted to allow them to have larger inbox quotas. =)

Remove-Variable * -ErrorAction SilentlyContinue; Remove-Module *; $error.Clear(); Clear-Host 

Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010

foreach($line in get-content "\\Server\Exports\Feed.txt")
{
    if (![string]::IsNullOrWhiteSpace($line))
    {
        $recipients = $line -split [RegEx]::Escape("|")
        Try
        {
            $EID = $recipients[1].trim()
            $EmpType = $recipients[17].trim()

            $User = Get-ADUser -LDAPFilter "(sAMAccountName=$EID)" -Properties Mail
            If ($User.mail -eq $Null) 
            {
                continue
            }


            $Mb = Get-Mailbox -Identity $EID 

            if (-not $Mb)
            {
                continue
            }

            if ($EmpType -eq "DIR")
            {
                if ($Mb.Database -ne "DB04" -and $Mb.Database -ne "DBA07")
                {
                    Write-Host $EID $EmpType $Mb.Database
                    New-MoveRequest -Identity $EID -TargetDatabase "DBA04" -WhatIf
                }
            }

            if ($EmpType -eq "ELT")
            {
                if ($Mb.Database -ne "DB07")
                {
                    Write-Host $EID $EmpType $Mb.Database
                    New-MoveRequest -Identity $EID -TargetDatabase "DBA07" -WhatIf
                }
            }
        }
        catch
        {
        }
    }
}

So during my practice of my Sonatina, I was in the Key of G Major, I was doing some deep thinking on converting it to its Parallel and Relative Keys, In this case, G Minor and D Minor. During this example, I thought on how that is the near order of the Major Scale. So normally when you translate from one key to another you can just walk down or up depending on which way you are converting 3 Simitones to your Relative key. I made a grid so you can see the pattern that starts to develop!

Here is a copy of a nice little powershell script I threw together to help maintain permissions on servers.

Remove-Variable * -ErrorAction SilentlyContinue; Remove-Module *; $error.Clear(); Clear-Host

$RootFSPath = "G:\users3"

Function GetFolderACL([string]$User, [bool]$Recursive) 
{
    $filePath = "$RootFSPath\$User"
    #Get-Acl -Path $filePath | Format-List
    $filePathacl = Get-Acl -Path $filePath
    if ($Recursive -eq $True)
    {
        $folders = Get-ChildItem $filePath -Recurse #-Directory
        foreach ($folder in $folders)
        {
            #Get-Acl -Path $folder.FullName | Format-List
            foreach ($access in $filePathacl.Access) 
            {
                if ($access.IdentityReference.Value -eq "YourDomain\$user" -and $access.FileSystemRights -eq "Modify, Synchronize") 
                {
                    continue
                }
                if ($access.IdentityReference.Value -eq "NT AUTHORITY\SYSTEM" -and $access.FileSystemRights -eq "FullControl") 
                {
                    continue
                }
                if ($access.IdentityReference.Value -eq "BUILTIN\Administrators" -and $access.FileSystemRights -eq "FullControl") 
                {
                    continue
                }
                if ($access.IdentityReference.Value -eq "YourDomain\Domain Admins" -and $access.FileSystemRights -eq "FullControl") 
                {
                    continue
                }
                Write-Host $access.IdentityReference $access.FileSystemRights
            }
        }
    }
}

Function GetFolderACLRecursive([string]$filePath, [string]$User,[bool]$Recursive) 
{

    if ($Recursive -eq $True)
    {
        $folders = Get-ChildItem $filePath -Recurse -Directory
        foreach ($folder in $folders)
        {
            GetFolderACLRecursive $folder.PSPath $true
        }
    }

    [bool]$UserPerm = $false
    [bool]$SystemPerm = $false
    [bool]$AdminPerm = $false
    [bool]$DomainAdminPerm = $false

    $Searcher = [ADSISearcher]"(sAMAccountName=$folder)"
    $Results = $Searcher.FindOne()

    If ($Results -eq $Null) 
    {
        if ($filePath -ne "$RootFSPath\")
        {
            #try your best not to wak the parent folder due to Hr's typeo's ;)
            Write-Host "$folder does not exist in AD, $filePath can be deleted... Deleting"
            Remove-Item –path $filePath –recurse -force
            $UserPerm = $true
        }
    }
    else #If they do exit check the ACLS
    {
        $filePathacl = Get-Acl -Path $filePath
        foreach ($access in $filePathacl.Access) 
        {
            if ($access.IdentityReference.Value -eq "YourDomain\$User" -and $access.FileSystemRights -eq "Modify, Synchronize") 
            {
                $UserPerm = $true
                continue
            }
            if ($access.IdentityReference.Value -eq "NT AUTHORITY\SYSTEM" -and $access.FileSystemRights -eq "FullControl") 
            {
                $SystemPerm = $true
                continue
            }
            if ($access.IdentityReference.Value -eq "BUILTIN\Administrators" -and $access.FileSystemRights -eq "FullControl") 
            {
                $AdminPerm = $true
                continue
            }
            if ($access.IdentityReference.Value -eq "YourDomain\Domain Admins" -and $access.FileSystemRights -eq "FullControl") 
            {
                $DomainAdminPerm = $true
                continue
            }

            Write-Host $filePath.PadRight(15) $access.IdentityReference $access.FileSystemRights 
        }

        if ($SystemPerm -eq $false)
        {
            Write-Host "Missing System Permission to $filePath"
        }

        if ($AdminPerm -eq $false)
        {
            Write-Host "Missing Admin Permission to $filePath"
        }

        if ($DomainAdminPerm -eq $false)
        {
            Write-Host "Missing DominAdmin Permission to $filePath"
        }

        if (($UserPerm -eq $false) -or ($SystemPerm -eq $false) -or ($AdminPerm -eq $false) -or ($DomainAdminPerm = $false))
        {
            return $false
        }
    }
}

Function SetFolderACL([string]$User, [bool]$Recursive, [bool]$EnableInheritance, [bool]$DisableInheritance) 
{  
    $filePath = "$RootFSPath\$User"
    $filePathacl = Get-Acl -Path $filePath

    if ($EnableInheritance -eq $True) #This should not happen if we are looking to disable Inheritance, We want to remove it from the parent folder last below in this code.
    {
        foreach ($access in $filePathacl.Access) 
        {
            #if ($access.IdentityReference.Value -eq $user) {
                #$acl.RemoveAccessRule($access) | Out-Null
                $filePathacl.RemoveAccessRule($access)
            #}
        }

        $filePathacl.SetAccessRuleProtection($false,$false)
        Set-Acl -Path $filePath -AclObject $filePathacl
    }

    if ($Recursive -eq $True)
    {
        $folders = Get-ChildItem $filePath -Recurse #-Directory
        foreach ($folder in $folders) 
        {
            $acl = Get-Acl -Path $folder.FullName

            Write-Host $folder.FullName

            if ($EnableInheritance -eq $True)
            {
                $acl.SetAccessRuleProtection($false,$false)
                Set-Acl -Path $folder.FullName -AclObject $acl
            }
            if ($DisableInheritance -eq $True)
            {
                $acl.SetAccessRuleProtection($true,$true)
                Set-Acl -Path $folder.FullName -AclObject $acl
            }

            foreach ($access in $acl.Access) {
                #if ($access.IdentityReference.Value -eq $user) {
                    #$acl.RemoveAccessRule($access) | Out-Null
                    $acl.RemoveAccessRule($access)
                #}
            }

            Set-Acl -Path $folder.FullName -AclObject $acl

        }
    }

    if ($DisableInheritance -eq $True) #This should not happen if we are looking to disable Inheritance, We want to remove it from the parent folder last below in this code.
    {
        $filePathacl = Get-Acl -Path $filePath   
        $filePathacl.SetAccessRuleProtection($true,$true)

        foreach ($access in $filePathacl.Access) 
        {
            #if ($access.IdentityReference.Value -eq $user) {
                #$acl.RemoveAccessRule($access) | Out-Null
                $filePathacl.RemoveAccessRule($access)
            #}
        }
        Set-Acl -Path $filePath -AclObject $filePathacl
    }

    $acl = Get-Acl -Path $filePath
    $permission = "YourDomain\$user", "Modify", "ContainerInherit, ObjectInherit", "None", "Allow"
    $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
    $acl.SetAccessRule($accessRule)
    $acl | Set-Acl $filepath
} 

Function SetStrightFolderACL([string]$User, [bool]$Recursive, [bool]$EnableInheritance, [bool]$DisableInheritance) 
{
    Write-Host $folder.FullName
    $filePath = "$RootFSPath\$User"
    $filePathacl = Get-Acl -Path $filePath
    $acl = Get-Acl -Path $filePath
    $permission = "YourDomain\$user", "Modify", "ContainerInherit, ObjectInherit", "None", "Allow"
    $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
    $acl.SetAccessRule($accessRule)
    $acl | Set-Acl $filepath 
}

$folders = Get-ChildItem "$RootFSPath" #-Recurse #-Directory
foreach ($folder in $folders) 
{
    $acl = Get-Acl -Path $folder.FullName
    #Write-Host (GetFolderACLRecursive "G:\users3\$folder" $folder $false)
    $result = GetFolderACLRecursive "$RootFSPath\$folder" $folder $false
    if ($result -eq $false)
    {
        $Searcher = [ADSISearcher]"(sAMAccountName=$folder)"
        $Results = $Searcher.FindOne()
        If ($Results -eq $Null) 
        {
            #Write-Host "Users does not exist in AD"
        }
        Else 
        {
            #Write-Host "User found in AD"
            SetFolderACL $folder.Name $true $false $True #Remove Inhairtance
            SetFolderACL $folder.Name $true $true $false #Enable Inhairtance
        }        
    }
    #Write-Host $folder.FullName
    #Write-Host $folder.Name
    #GetFolderACL $folder.Name $false
    #SetStrightFolderACL $folder.Name $true $true $false #Enable Inhairtance
    #SetFolderACL $user $true $true $false #Enable Inhairtance
}

exit

#GetFolderACL $user $true
SetFolderACL $user $true $false $True #Remove Inhairtance
SetFolderACL $user $true $true $false #Enable Inhairtance

exit

SetFolderACL $user $true $false $True #Remove Inhairtance

exit

SetFolderACL $user $true $true $false #Enable Inhairtance

exit

So recently I’ve been tasking with cleaning up an SQL database for a developing project I’ve been working on for EPIC and User Provisioning. I had two end up merging two table sets together to get the data I needed, However, duplicate rows impact the process, So I used the following commands below to filter through the Datasets and find the Duped rows to delete all but just one of the instances.

SELECT     COUNT(*) AS Expr2, Dept, JobCode, RightsItem, RightsValue AS Expr1
FROM         (SELECT     TOP (100) PERCENT AppName, Dept, JobCode, RightsItem, RightsValue, Entity
                       FROM          dbo.AppRights
                       WHERE      (AppName LIKE 'EPIC')) AS derivedtbl_1

GROUP BY Dept, JobCode, RightsItem, RightsValue
HAVING      (COUNT(*) > 1)



SELECT     AppName, Dept, JobCode, RightsItem, RightsValue, Entity, ID
FROM         dbo.AppRights
WHERE     (ID IN
                          (SELECT     id AS Expr1
                            FROM          (SELECT     TOP (100) PERCENT AppName, Dept, JobCode, RightsItem, RightsValue, Entity, ID
                                                    FROM          dbo.AppRights AS AppRights_1
                                                    WHERE      (AppName LIKE 'EPIC')
                                                    ORDER BY RightsItem) AS derivedtbl_1
                            GROUP BY Dept, JobCode, RightsItem, RightsValue
                            HAVING      (COUNT(*) > 1)))

WITH g AS (
    SELECT ROW_NUMBER() OVER(PARTITION BY AppName, Dept, JobCode, RightsItem, RightsValue, Entity order by Dept) AS row
    FROM dbo.AppRights) 
delete FROM g
WHERE row > 1

So, I’m once in a bluemoon I end up with a 8AM surprise calendar event when I am out of the office the day before. I threw this little gem together using powershell that will send me an email and a text message to my phone throughout the day if one of these meetings appear the next day in the bright AM. Better that then to be supprised that your already 5 minutes behind on a meeting that started at 8AM by the time you get to your Emal and Calendar for the morning.

#https://download.microsoft.com/download/8/9/9/899EEF2C-55ED-4C66-9613-EE808FCF861C/EwsManagedApi.msi
#Declare Variables
$EWSDLL = "C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll"
$MBX = "YourEmail@Domain.org"
$EWSURL = "https://FQDN.Domain.Com/EWS/Exchange.asmx"
$StartDate = (Get-Date)
$EndDate = (Get-Date).AddDays(1)  

#Binding of the calendar of the Mailbox and EWS
Import-Module -Name $EWSDLL
$mailboxname = $MBX
$service = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.Exchangeversion]::exchange2010)
$service.Url = new-object System.Uri($EWSURL)
$userName="SamAccountIDWithoutDomain"
$password="Your Email password"
#Uncomment to use Auth in lieu of passthrough
#$service.Credentials = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials -ArgumentList $userName, $password
$folderid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar,$MailboxName) 
$Calendar = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)  
$Recurring = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition([Microsoft.Exchange.WebServices.Data.DefaultExtendedPropertySet]::Appointment, 0x8223,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Boolean); 
$psPropset= new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)  
$psPropset.Add($Recurring)
$psPropset.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text;

$RptCollection = @()

$AppointmentState = @{0 = "None" ; 1 = "Meeting" ; 2 = "Received" ;4 = "Canceled" ; }

#Define the calendar view  
$CalendarView = New-Object Microsoft.Exchange.WebServices.Data.CalendarView($StartDate, $EndDate, 1000)    
$fiItems = $service.FindAppointments($Calendar.Id,$CalendarView)
if($fiItems.Items.Count -gt 0){
 $type = ("System.Collections.Generic.List"+'`'+"1") -as "Type"
 $type = $type.MakeGenericType("Microsoft.Exchange.WebServices.Data.Item" -as "Type")
 $ItemColl = [Activator]::CreateInstance($type)
 foreach($Item in $fiItems.Items){
  $ItemColl.Add($Item)
 } 
 [Void]$service.LoadPropertiesForItems($ItemColl,$psPropset)  
}

$min = Get-Date '08:00'
$max = Get-Date '08:29'

foreach($Item in $fiItems.Items){      
 $rptObj = "" | Select StartTime,EndTime,Duration,Type,Subject,Location,Organizer,Attendees,AppointmentState,Notes,HasAttachments,IsReminderSet
 $rptObj.StartTime = $Item.Start  
 $rptObj.EndTime = $Item.End  
 $rptObj.Duration = $Item.Duration
 $rptObj.Subject  = $Item.Subject   
 $rptObj.Type = $Item.AppointmentType
 $rptObj.Location = $Item.Location
 $rptObj.Organizer = $Item.Organizer.Address
 $rptObj.HasAttachments = $Item.HasAttachments
 $rptObj.IsReminderSet = $Item.IsReminderSet
 $aptStat = "";
 $AppointmentState.Keys | where { $_ -band $Item.AppointmentState } | foreach { $aptStat += $AppointmentState.Get_Item($_) + " "}
 $rptObj.AppointmentState = $aptStat 
 $RptCollection += $rptObj
 foreach($attendee in $Item.RequiredAttendees){
  $atn = $attendee.Address + "; "  
  $rptObj.Attendees += $atn
  }
 foreach($attendee in $Item.OptionalAttendees){
  $atn = $attendee.Address + "; "  
  $rptObj.Attendees += $atn
 }
 foreach($attendee in $Item.Resources){
  $atn = $attendee.Address + "; "  
  $rptObj.Resources += $atn
 }
 $rptObj.Notes = $Item.Body.Text
#Display on the screen
 #"Start:   " + $Item.Start  
 #"Subject: " + $Item.Subject 


 if ($min.TimeOfDay -le $rptObj.StartTime.TimeOfDay -and $max.TimeOfDay -ge $rptObj.StartTime.TimeOfDay) {

        $message = New-Object Microsoft.Exchange.WebServices.Data.EmailMessage $Service
        $message.Subject = "REMINDER!! " + $Item.Subject          
        $message.Body = new-object Microsoft.Exchange.WebServices.Data.MessageBody([Microsoft.Exchange.WebServices.Data.BodyType]::Text, ($rptObj | Format-List | Out-String) -replace '\n(?=")','<br/>')

        foreach ($file in $Attachment) {
            $null = $message.Attachments.AddFileAttachment($file)
        }
        foreach ($recipient in $To) {
            $null = $message.ToRecipients.Add(
                $recipient    
            )
        }
        foreach ($recipient in $Cc) {
            $null = $message.CcRecipients.Add(
                $recipient
            )
        }
        foreach ($recipient in $Bcc) {
            $null = $message.BccRecipients.Add(
                $recipient
            )
        }
        $message.ToRecipients.Add("ToWhomeGetsTheReminder@Domain.Com")
        $message.ToRecipients.Add("9998887777@vtext.com")
        $message.SendAndSaveCopy()

        $PR_DEF_POST_MSGCLASS_W = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x36E5,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String)
        $PR_DEF_POST_DISPLAYNAME_W = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x36E6,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String)
        $PR_DEFERRED_SEND_TIME = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(16367, [Microsoft.Exchange.WebServices.Data.MapiPropertyType]::SystemTime)

        $message.Subject = "2ND REMINDER!! " + $Item.Subject
        $sendTime = [System.DateTime]::Now.AddHours(2)
        $message.SetExtendedProperty($PR_DEFERRED_SEND_TIME, $sendTime)
        $message.SendAndSaveCopy()

        $message.Subject = "LAST REMINDER!! " + $Item.Subject
        $sendTime = [datetime]::ParseExact("07:00","hh:mm",$null).AddDays(1)
        $message.SetExtendedProperty($PR_DEFERRED_SEND_TIME, $sendTime)
        $message.SendAndSaveCopy()
        #$message
        #$message.ExtendedProperties  | Format-List | Out-String
        #Write-Host $rptObj | Format-List | Out-String
 }

}   
#Export to a CSVFile
#$RptCollection |  Export-Csv -NoTypeInformation -Path "c:\$MailboxName-CalendarCSV.csv"
#pause
# https://download.microsoft.com/download/8/9/9/899EEF2C-55ED-4C66-9613-EE808FCF861C/EwsManagedApi.msi

Remove-Variable * -ErrorAction SilentlyContinue; Remove-Module *; $error.Clear(); Clear-Host #You cannot use this with Param

# Declare Variables

$EWSDLL = "C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll" $MBX = "YourEmail@Domain.org" $EWSURL = "https://FQDN.Domain.Com/EWS/Exchange.asmx" $StartDate = (Get-Date) $EndDate = [datetime]::ParseExact("23:59","HH:mm",$null)

# Binding of the calendar of the Mailbox and EWS

Import-Module -Name $EWSDLL $mailboxname = $MBX $service = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.Exchangeversion]::exchange2010) $service.Url = new-object System.Uri($EWSURL) $userName="SamAccountIDWithoutDomain" $password="Your Email password"

# Uncomment to use Auth in lieu of passthrough

# $service.Credentials = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials -ArgumentList $userName, $password

$folderid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar,$MailboxName) $Calendar = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)  
$Recurring = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition([Microsoft.Exchange.WebServices.Data.DefaultExtendedPropertySet]::Appointment, 0x8223,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Boolean); $psPropset= new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)  
$psPropset.Add($Recurring) $psPropset.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text;

$RptCollection = @()

$AppointmentState = @{0 = "None" ; 1 = "Meeting" ; 2 = "Received" ;4 = "Canceled" ; }

# Define the calendar view

$CalendarView = New-Object Microsoft.Exchange.WebServices.Data.CalendarView($StartDate, $EndDate, 1000)  
$fiItems = $service.FindAppointments($Calendar.Id,$CalendarView) if($fiItems.Items.Count -gt 0){ $type = ("System.Collections.Generic.List"+'`'+"1") -as "Type" $type = $type.MakeGenericType("Microsoft.Exchange.WebServices.Data.Item" -as "Type") $ItemColl = [Activator]::CreateInstance($type) foreach($Item in $fiItems.Items){ $ItemColl.Add($Item) } [Void]$service.LoadPropertiesForItems($ItemColl,$psPropset)  
}

$min = Get-Date '08:00' $max = Get-Date '08:29'

foreach($Item in $fiItems.Items) {  
$rptObj = "" | Select StartTime,EndTime,Duration,Type,Subject,Location,Organizer,Attendees,AppointmentState,Notes,HasAttachments,IsReminderSet,ReminderDueBy,ReminderMinutesBeforeStart $rptObj.StartTime = $Item.Start  
$rptObj.EndTime = $Item.End  
$rptObj.Duration = $Item.Duration $rptObj.Subject = $Item.Subject  
$rptObj.Type = $Item.AppointmentType $rptObj.Location = $Item.Location $rptObj.Organizer = $Item.Organizer.Address $rptObj.HasAttachments = $Item.HasAttachments $rptObj.IsReminderSet = $Item.IsReminderSet $rptObj.ReminderDueBy = $Item.ReminderDueBy $rptObj.ReminderMinutesBeforeStart = $Item.ReminderMinutesBeforeStart $aptStat = ""; $AppointmentState.Keys | where { $_ -band $Item.AppointmentState } | foreach { $aptStat += $AppointmentState.Get_Item($_) + " "} $rptObj.AppointmentState = $aptStat $RptCollection += $rptObj foreach($attendee in $Item.RequiredAttendees){ $atn = $attendee.Address + "; "  
$rptObj.Attendees += $atn } foreach($attendee in $Item.OptionalAttendees){ $atn = $attendee.Address + "; "  
$rptObj.Attendees += $atn } foreach($attendee in $Item.Resources){ $atn = $attendee.Address + "; "  
$rptObj.Resources += $atn } $rptObj.Notes = $Item.Body.Text #Display on the screen #"Start: " + $Item.Start  
#"Subject: " + $Item.Subject

    if ($rptObj.ReminderMinutesBeforeStart = 0 -or $Item.IsReminderSet -eq $false) {

        $message = New-Object Microsoft.Exchange.WebServices.Data.EmailMessage $Service
        $message.Subject = "REMINDER SET TO ZERO!! " + $Item.Subject          
        $message.Body = new-object Microsoft.Exchange.WebServices.Data.MessageBody([Microsoft.Exchange.WebServices.Data.BodyType]::Text, ($rptObj | Format-List | Out-String) -replace '\n(?=")','<br/>')

        foreach ($file in $Attachment) {
            $null = $message.Attachments.AddFileAttachment($file)
        }
        foreach ($recipient in $To) {
            $null = $message.ToRecipients.Add(
                $recipient    
            )
        }
        foreach ($recipient in $Cc) {
            $null = $message.CcRecipients.Add(
                $recipient
            )
        }
        foreach ($recipient in $Bcc) {
            $null = $message.BccRecipients.Add(
                $recipient
            )
        }
        $message.ToRecipients.Add("ToWhomeGetsTheReminder@Domain.Com")
            $message.ToRecipients.Add("9998887777@vtext.com")
        $message.SendAndSaveCopy()
        #$message
        #$message.ExtendedProperties  | Format-List | Out-String
        #Write-Host $rptObj | Format-List | Out-String
    }
    else
    {
        $Item.Subject
        $Item.IsReminderSet
        $Item.ReminderDueBy
        $Item.ReminderMinutesBeforeStart
        Write-Host "=-=-=-=-=-="
    }


}

# Export to a CSVFile

# $RptCollection | Export-Csv -NoTypeInformation -Path "c:\$MailboxName-CalendarCSV.csv"

# pause

So in the last day, A buddy of mine pointed out an issue with LanDesk ISSUR. I got to a stopping point but basically when you try to Kill the process while it is in a hung state it. So my thoughts were the ACL in memory for the process was adjusted to prevent administrators from killing the process. After running this code I found the process does not even have a handle to begin pulling its ACL. Interesting trick, Something that warrants further research.

Update: I am unable to get access to the process handle due to the ACL’s I must escalate to system first before this API will work.
Src: http://csharptest.net/1043/how-to-prevent-users-from-killing-your-service-process/index.html Also an interesting read.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Principal;
using System.ServiceProcess;
using System.Text;
using System.Windows.Forms;

namespace ProcessPermissions
{
    public partial class Form1 : Form
    {

        [StructLayoutAttribute(LayoutKind.Sequential)]
        struct SECURITY_DESCRIPTOR
        {
            public byte revision;
            public byte size;
            public short control;
            public IntPtr owner;
            public IntPtr group;
            public IntPtr sacl;
            public IntPtr dacl;
        }

        [DllImport("advapi32.dll", SetLastError = true)]
        static extern bool QueryServiceObjectSecurity(IntPtr serviceHandle,
            System.Security.AccessControl.SecurityInfos secInfo,
            ref SECURITY_DESCRIPTOR lpSecDesrBuf,
            uint bufSize,
            out uint bufSizeNeeded);

        [DllImport("advapi32.dll", SetLastError = true)]
        static extern bool QueryServiceObjectSecurity(SafeHandle serviceHandle,
            System.Security.AccessControl.SecurityInfos secInfo,
            byte[] lpSecDesrBuf,
            uint bufSize,
            out uint bufSizeNeeded);

        [DllImport("advapi32.dll", SetLastError = true)]
        static extern bool SetServiceObjectSecurity(SafeHandle serviceHandle,
            System.Security.AccessControl.SecurityInfos secInfos,
            byte[] lpSecDesrBuf);

        public void SetServicePermissions(string service, string username)
        {
            System.ServiceProcess.ServiceController sc = new System.ServiceProcess.ServiceController(service, ".");
            ServiceControllerStatus status = sc.Status;
            byte[] psd = new byte[0];
            uint bufSizeNeeded;
            bool ok = QueryServiceObjectSecurity(sc.ServiceHandle, SecurityInfos.DiscretionaryAcl, psd, 0, out bufSizeNeeded);
            if (!ok)
            {
                int err = Marshal.GetLastWin32Error();
                if (err == 122 || err == 0)
                { // ERROR_INSUFFICIENT_BUFFER
                  // expected; now we know bufsize
                    psd = new byte[bufSizeNeeded];
                    ok = QueryServiceObjectSecurity(sc.ServiceHandle, SecurityInfos.DiscretionaryAcl, psd, bufSizeNeeded, out bufSizeNeeded);
                }
                else {
                    throw new ApplicationException("error calling QueryServiceObjectSecurity() to get DACL for : error code=" + err);
                }
            }
            if (!ok)
                throw new ApplicationException("error calling QueryServiceObjectSecurity(2) to get DACL for : error code=" + Marshal.GetLastWin32Error());

            // get security descriptor via raw into DACL form so ACE
            // ordering checks are done for us.
            RawSecurityDescriptor rsd = new RawSecurityDescriptor(psd, 0);
            RawAcl racl = rsd.DiscretionaryAcl;
            DiscretionaryAcl dacl = new DiscretionaryAcl(false, false, racl);

            // Add start/stop/read access
            NTAccount acct = new NTAccount(username);
            SecurityIdentifier sid = (SecurityIdentifier)acct.Translate(typeof(SecurityIdentifier));
            // 0xf7 is SERVICE_QUERY_CONFIG|SERVICE_CHANGE_CONFIG|SERVICE_QUERY_STATUS|
            // SERVICE_START|SERVICE_STOP|SERVICE_PAUSE_CONTINUE|SERVICE_INTERROGATE
            dacl.AddAccess(AccessControlType.Allow, sid, 0xf7, InheritanceFlags.None, PropagationFlags.None);

            // convert discretionary ACL back to raw form; looks like via byte[] is only way
            byte[] rawdacl = new byte[dacl.BinaryLength];
            dacl.GetBinaryForm(rawdacl, 0);
            rsd.DiscretionaryAcl = new RawAcl(rawdacl, 0);

            // set raw security descriptor on service again
            byte[] rawsd = new byte[rsd.BinaryLength];
            rsd.GetBinaryForm(rawsd, 0);
            ok = SetServiceObjectSecurity(sc.ServiceHandle, SecurityInfos.DiscretionaryAcl, rawsd);
            if (!ok)
            {
                throw new ApplicationException("error calling SetServiceObjectSecurity(); error code=" + Marshal.GetLastWin32Error());
            }
        }

        [DllImport("advapi32.dll", SetLastError = true)]
        static extern bool GetKernelObjectSecurity(IntPtr Handle, int securityInformation, [Out] byte[] pSecurityDescriptor,
        uint nLength, out uint lpnLengthNeeded);

        public static RawSecurityDescriptor GetProcessSecurityDescriptor(IntPtr processHandle)
        {
            const int DACL_SECURITY_INFORMATION = 0x00000004;
            byte[] psd = new byte[0];
            uint bufSizeNeeded;
            // Call with 0 size to obtain the actual size needed in bufSizeNeeded
            GetKernelObjectSecurity(processHandle, DACL_SECURITY_INFORMATION, psd, 0, out bufSizeNeeded);
            if (bufSizeNeeded < 0 || bufSizeNeeded > short.MaxValue)
                throw new Win32Exception();
            // Allocate the required bytes and obtain the DACL
            if (!GetKernelObjectSecurity(processHandle, DACL_SECURITY_INFORMATION,
            psd = new byte[bufSizeNeeded], bufSizeNeeded, out bufSizeNeeded))
                throw new Win32Exception();
            // Use the RawSecurityDescriptor class from System.Security.AccessControl to parse the bytes:
            return new RawSecurityDescriptor(psd, 0);
        }
        string GetNameFromSID(SecurityIdentifier sid)
        {
            try
            {
                NTAccount ntAccount = (NTAccount)sid.Translate(typeof(NTAccount));
                return ntAccount.ToString();
            }
            catch
            {
                return null;
            }
        }
        public Form1()
        {
            InitializeComponent();
        }
        [DllImport("kernel32.dll")]
        public static extern bool WriteProcessMemory(int hProcess, int lpBaseAddress, byte lpBuffer,
                                         int nSize, int lpNumberOfBytesWritten);
        [DllImport("kernel32.dll")]
        public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
        int PROCESS_ALL_ACCESS = (0x1F0FFF);

        private void Form1_Load(object sender, EventArgs e)
        {
            //IntPtr hProcess = IntPtr.Zero;
            IntPtr hProcessToken = IntPtr.Zero;
            IntPtr securityDescriptorPtr = IntPtr.Zero;
            //Process[] hProcess = Process.GetProcessesByName("issuser");
            Process[] hProcess = Process.GetProcessesByName("notepad");
            IntPtr xAsIntPtr = new IntPtr(hProcess[0].Id);
            RawSecurityDescriptor Desc = GetProcessSecurityDescriptor(xAsIntPtr);
            System.Diagnostics.Debug.WriteLine(Desc.Owner);

            foreach (CommonAce item in Desc.DiscretionaryAcl)
            {
                System.Diagnostics.Debug.WriteLine(item.SecurityIdentifier.Value + " - " + item.SecurityIdentifier.AccountDomainSid);
                System.Diagnostics.Debug.WriteLine(GetNameFromSID(item.SecurityIdentifier));
                System.Diagnostics.Debug.WriteLine(item.AceFlags);
                System.Diagnostics.Debug.WriteLine(item.AceType);
                System.Diagnostics.Debug.WriteLine(item.AuditFlags);
                System.Diagnostics.Debug.WriteLine(item.BinaryLength);
                System.Diagnostics.Debug.WriteLine(item.InheritanceFlags);
                System.Diagnostics.Debug.WriteLine(item.IsInherited);
                System.Diagnostics.Debug.WriteLine(item.PropagationFlags);
                System.Diagnostics.Debug.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
            }

            Application.Exit(); 
        }
    }
}

Checking the status of active users and disabling them if required.

REST is used to create users

    #Param must be the first executable line
Param(
    [string] $ContactComment = "Inital Entry",
    [string] $SystemLoginID = "12345",
    [string] $IsActive = "0",
    [string] $Name = "HALL, NICHOLAS A",
    [string] $DefaultTemplateID = "T1201",
    [string] $AppliedTemplateID = "T1201",
    [string] $LinkedTemplateID1 = "T1201",
    [string] $LinkedTemplateID2 = "T2100303",
    [string] $UserSubtemplateIDs1 = "T063",
    [string] $UserSubtemplateIDs2 = "ST5083",
    [string] $CustomUserDictionaries = "\\\\epic-server\\User_Dictionaries\\12345dictionary.tlx"
 )

#Remove-Variable * -ErrorAction SilentlyContinue; Remove-Module *; $error.Clear(); Clear-Host

#https://vm9008.info.sys/Interconnect-REL-EDI/DeveloperView/Main.aspx?clientid=1

$Request = '{"LinkedTemplatesConfig":{"DefaultTemplateID":{"ID":"' + $DefaultTemplateID + '","Type":"external"},"AppliedTemplateID":{"ID":"' + "$AppliedTemplateID" + '","Type":"external"},"AvailableLinkableTemplates":[{"StartDate":"","EndDate":"","LoginTypes":[],"LinkedTemplateID":{"ID":"' + "$LinkedTemplateID1" + '","Type":"external"}},{"StartDate":"","EndDate":"","LoginTypes":[],"LinkedTemplateID":{"ID":"' + "$LinkedTemplateID2" + '","Type":"external"}}]},"UserSubtemplateIDs":[{"Index":"1","Identifier":{"ID":"' + "$UserSubtemplateIDs1" + '","Type":"external"}},{"Index":"2","Identifier":{"ID":"' + "$UserSubtemplateIDs2" + '","Type":"external"}}],"CustomUserDictionaries":[{"Index":"1","Value":"' + $CustomUserDictionaries + '"}],"LinkedProviderID":{"ID":"","Type":""},"IdentityIDs":[],"ExternalIdentifiers":[{"Identifier":"e12345","IdentifierType":"EMC Mckesson Document Imaging","IsActive":"true"}]}'
try
{
    $RestResults = Invoke-RestMethod -Method Put $url -contentType "application/json" -Body $Request
    foreach($id in $RestResults.UserIDs)
    {
        Write-Host $id.ID - $id.Type
    }
    if ($RestResults.UserIDs.Count -eq 4)
    {
        Write-Host "SUCCESS!"
    }
    $RestResults.Messages
}
catch
{
    if ($_.exception.Response.StatusCode -eq "BadRequest")
    {
        #$_.exception.Response.StatusDescription
        if ($_.exception.Response.StatusDescription -match '^.*System login ID must be unique\.')
        {
            Write-Host "Already Exist!"
        }
        else
        {
            Write-Host "BadRequest: " $_.exception.Response.StatusDescription
        }
    }
    else
    { 
        $_.Exception | gm
        $_.Exception | Select-Object -Property *
        $_.exception.Response.StatusCode
    }
    #$_.exception.message
    #$_.exception.InnerException
    #$_.Exception.ItemName
}

WSDL is used to Terminate/SoftDelete / Inactivate users

Remove-Variable * -ErrorAction SilentlyContinue; Remove-Module *; $error.Clear(); Clear-Host

$where = 'https://EpicServer/Interconnect-REL-EDI/wcf/Epic.Security.GeneratedServices/PersonnelManagement.svc'
$ws = New-WebServiceProxy -uri $where -UseDefaultCredential 

$namespace = $ws.getType().namespace

foreach($line in get-content "c:\termList.txt")
{
    try
    {
        $recipients = $line -split [RegEx]::Escape("|")
        $samAccountName = $recipients[1].trim()
        [Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy61rvices_PersonnelManagement_svc.PersonnelManagementViewUserResponse] $ViewUserResponse = $ws.ViewUser($samAccountName, "SystemLogin", $null, $null, $null, $false, $null)
        if ($ViewUserResponse.IsActive)
        {
            Write-Host "Is user active in REL:" $samAccountName
        }
    }
    catch
    {
    }
}

pause

[Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy61rvices_PersonnelManagement_svc.PersonnelManagementInactivateUserResponse] $response = $ws.InactivateUser($samAccountName, "SystemLogin", $null, $null, $null)
Write-Host "Messages:" $response.Messages

[Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy61rvices_PersonnelManagement_svc.PersonnelManagementViewUserResponse] $ViewUserResponse = $ws.ViewUser($samAccountName, "SystemLogin", $null, $null, $null, $false, $null)
Write-Host "Is user active:" $ViewUserResponse.IsActive

pause

[Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy61rvices_PersonnelManagement_svc.PersonnelManagementActivateUserResponse] $ActivateResponse = $ws.ActivateUser($samAccountName, "SystemLogin", $null, $null, $null)
Write-Host "Messages:" $ActivateResponse.Messages

[Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy61rvices_PersonnelManagement_svc.PersonnelManagementViewUserResponse] $ViewUserResponse = $ws.ViewUser($samAccountName, "SystemLogin", $null, $null, $null, $false, $null)
Write-Host "Is User Active:" $ViewUserResponse.IsActive