Category: Uncategorized

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

So, When I am taking an exam that requires me to read a full PDF, and in this case 400+ pages. I found this neat little trick.

https://pdf2jpg.net Convert’s any PDF less than 25MB to thumbnail images.

Using this way, I then target the folder full of the pictures and it dumps all the data to a text file.
Then I use the dumped data to translates from Google translator from English to English then I click the Microphone to start to read the text.

Imports Tesseract
Imports System.Threading
Imports System.Runtime.InteropServices
Imports System.IO

Public Class Form1

    Public Const MOD_ALT As Integer = &H1 'Alt key
    Public Const WM_HOTKEY As Integer = &H312

    <DllImport("User32.dll")>
    Public Shared Function RegisterHotKey(ByVal hwnd As IntPtr,
                        ByVal id As Integer, ByVal fsModifiers As Integer,
                        ByVal vk As Integer) As Integer
    End Function

    <DllImport("User32.dll")>
    Public Shared Function UnregisterHotKey(ByVal hwnd As IntPtr,
                        ByVal id As Integer) As Integer
    End Function

    <DllImport("dwmapi.dll", PreserveSig:=False)>
    Public Shared Function DwmIsCompositionEnabled() As Boolean
    End Function

    <DllImport("dwmapi.dll", PreserveSig:=False)>
    Public Shared Sub DwmEnableComposition(ByVal bEnable As Boolean)
    End Sub

    <DllImport("user32.dll", EntryPoint:="GetCursorInfo")>
    Public Shared Function GetCursorInfo(ByRef pci As CURSORINFO) As Boolean
    End Function

    <DllImport("user32.dll", EntryPoint:="CopyIcon")>
    Public Shared Function CopyIcon(ByVal hIcon As IntPtr) As IntPtr
    End Function

    <DllImport("user32.dll", EntryPoint:="GetIconInfo")>
    Public Shared Function GetIconInfo(ByVal hIcon As IntPtr, ByRef piconinfo As ICONINFO) As Boolean
    End Function

    Dim aeroIsEnabled As Boolean
    Dim b As Bitmap
    Dim graphics As Graphics

    Dim StartPoint As New Point(0, 0)
    Dim ScreenShotSize As Drawing.Size
    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        If m.Msg = WM_HOTKEY Then
            Dim id As IntPtr = m.WParam
            Select Case (id.ToString)
                Case "100"
                    Debug.WriteLine("You pressed ALT+S key combination")
                    If StartPoint.IsEmpty Then
                        StartPoint = GetCursorPosition()
                        Debug.WriteLine(StartPoint)
                    Else
                        Dim MyEndPoint As Point = GetCursorPosition()
                        Debug.WriteLine(MyEndPoint)
                        Dim MyTwoPoints As New Point(MyEndPoint.X - StartPoint.X, MyEndPoint.Y - StartPoint.Y)
                        ScreenShotSize = New Size(MyTwoPoints)
                        Debug.WriteLine(ScreenShotSize)
                        'CaptureScreenshot(New Point(0, 0), PictureBox1.Size)
                        'This resizes the Background of the image to scale
                        If True Then
                            b = New Bitmap(PictureBox1.Size.Width, PictureBox1.Size.Height)
                        Else
                            b = New Bitmap(MyEndPoint.X - StartPoint.X, MyEndPoint.Y - StartPoint.Y)
                        End If
                        'ResizeImage(b, b.Width * 3, b.Height * 3)

                        PictureBox1.Image = b
                        graphics = Graphics.FromImage(b)
                        '
                        graphics.Clear(Color.Transparent)
                        graphics.CopyFromScreen(StartPoint, New Point(0, 0), ScreenShotSize)

                        Dim output As New Bitmap(ScreenShotSize.Width * 2, ScreenShotSize.Height * 2)
                        Using g As Graphics = Graphics.FromImage(output)
                            g.DrawImage(b, 0, 0, PictureBox1.Size.Width * 2, PictureBox1.Size.Height * 2)
                        End Using
                        PictureBox1.Image = output
                        'PictureBox1.Image.Save("./saved.tiff", System.Drawing.Imaging.ImageFormat.Tiff)
                        'ResizeImage(b, b.Width * 3, b.Height * 3)
                        '
                        StartPoint = New Point(0, 0)

                        Application.DoEvents()
                        translateFromMemory(ConvertToByteArray(output))
                        'translateFromFile("./saved.tiff")
                        'translateFromMemory(ConvertToByteArray(New Bitmap(ScreenShotSize.Width, ScreenShotSize.Height, graphics)))
                    End If

                Case "200"
                    MessageBox.Show("You pressed ALT+C key combination")
            End Select
        End If
        MyBase.WndProc(m)
    End Sub

    Public Shared Function ConvertToByteArray(ByVal value As Bitmap) As Byte()
        Dim ms = New System.IO.MemoryStream
        value.Save(ms, System.Drawing.Imaging.ImageFormat.Tiff) ' Use appropriate format here
        Dim bytes = ms.ToArray()
        Return bytes
    End Function

#Region " ResizeImage "
    Public Overloads Shared Function ResizeImage(SourceImage As Drawing.Image, TargetWidth As Int32, TargetHeight As Int32) As Drawing.Bitmap
        Dim bmSource = New Drawing.Bitmap(SourceImage)

        Return ResizeImage(bmSource, TargetWidth, TargetHeight)
    End Function

    Public Overloads Shared Function ResizeImage(bmSource As Drawing.Bitmap, TargetWidth As Int32, TargetHeight As Int32) As Drawing.Bitmap
        Dim bmDest As New Drawing.Bitmap(TargetWidth, TargetHeight, Drawing.Imaging.PixelFormat.Format32bppArgb)

        Dim nSourceAspectRatio = bmSource.Width / bmSource.Height
        Dim nDestAspectRatio = bmDest.Width / bmDest.Height

        Dim NewX = 0
        Dim NewY = 0
        Dim NewWidth = bmDest.Width
        Dim NewHeight = bmDest.Height

        If nDestAspectRatio = nSourceAspectRatio Then
            'same ratio
        ElseIf nDestAspectRatio > nSourceAspectRatio Then
            'Source is taller
            NewWidth = Convert.ToInt32(Math.Floor(nSourceAspectRatio * NewHeight))
            NewX = Convert.ToInt32(Math.Floor((bmDest.Width - NewWidth) / 2))
        Else
            'Source is wider
            NewHeight = Convert.ToInt32(Math.Floor((1 / nSourceAspectRatio) * NewWidth))
            NewY = Convert.ToInt32(Math.Floor((bmDest.Height - NewHeight) / 2))
        End If

        Using grDest = Drawing.Graphics.FromImage(bmDest)
            With grDest
                .CompositingQuality = Drawing.Drawing2D.CompositingQuality.HighQuality
                .InterpolationMode = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
                .PixelOffsetMode = Drawing.Drawing2D.PixelOffsetMode.HighQuality
                .SmoothingMode = Drawing.Drawing2D.SmoothingMode.AntiAlias
                .CompositingMode = Drawing.Drawing2D.CompositingMode.SourceOver

                .DrawImage(bmSource, NewX, NewY, NewWidth, NewHeight)
            End With
        End Using

        Return bmDest
    End Function
#End Region

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' Add any initialization after the InitializeComponent() call.
        'b = New Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)
        b = New Bitmap(PictureBox1.Size.Width, PictureBox1.Size.Height)
        PictureBox1.Image = b
        graphics = Graphics.FromImage(b)

        Me.DisableAero()

        RegisterHotKey(Me.Handle, 100, MOD_ALT, Keys.S)

        'PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
        'translateFromFile("./saved.tiff")
    End Sub

    Private Sub Form1_FormClosing(ByVal sender As System.Object,
                        ByVal e As System.Windows.Forms.FormClosingEventArgs) _
                        Handles MyBase.FormClosing
        UnregisterHotKey(Me.Handle, 100)
        UnregisterHotKey(Me.Handle, 200)
    End Sub

    Private Sub DisableAero()
        Try
            aeroIsEnabled = DwmIsCompositionEnabled()
            If aeroIsEnabled = True Then
                DwmEnableComposition(False)
            End If
        Catch ex As Exception
        End Try

    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        'Timer1.Stop()
        CaptureScreenshot(New Point(0, 0), PictureBox1.Size)
        'Timer1.Start()
    End Sub

    Private Function CaptureScreenshot(startPoint As Point, DrawingSize As Size) As Boolean
        Try
            If b IsNot Nothing Then

                'graphics.CopyFromScreen(Screen.PrimaryScreen.Bounds.Location, New Point(0, 0), Screen.PrimaryScreen.Bounds.Size)
                'Dim newDrawingSize As New System.Drawing.Size(PictureBox1.Size)
                'graphics.CopyFromScreen(New Point(x, y), startPoint, DrawingSize)
                'graphics.CopyFromScreen(startPoint, New Point(0, 0), DrawingSize, CopyPixelOperation.SourceAnd)
                graphics.CopyFromScreen(startPoint, New Point(0, 0), DrawingSize)
                If False Then
                    Dim x As Integer
                    Dim y As Integer
                    Dim cursorBmp As Bitmap = CaptureCursor(x, y)
                    'Draws Cursor on picture
                    graphics.DrawImage(cursorBmp, x, y)
                    cursorBmp.Dispose()
                    'Cursor.Draw(graphics, New Rectangle(Cursor.Position, Cursor.Size))
                End If

                Me.Refresh()
            End If
        Catch ex As Exception

        End Try
    End Function

    Private Shared Function CaptureCursor(ByRef x As Integer, ByRef y As Integer) As Bitmap
        Dim bmp As Bitmap
        Dim hicon As IntPtr
        Dim ci As New CURSORINFO()
        Dim icInfo As ICONINFO
        ci.cbSize = Marshal.SizeOf(ci)
        If GetCursorInfo(ci) Then
            hicon = CopyIcon(ci.hCursor)
            If GetIconInfo(hicon, icInfo) Then
                x = ci.ptScreenPos.X - CInt(icInfo.xHotspot)
                y = ci.ptScreenPos.Y - CInt(icInfo.yHotspot)
                Dim ic As Icon = Icon.FromHandle(hicon)
                bmp = ic.ToBitmap()
                ic.Dispose()
                Return bmp
            End If
        End If
        Return Nothing
    End Function

    Private Shared Function GetCursorPosition() As Point
        Dim hicon As IntPtr
        Dim ci As New CURSORINFO()
        Dim icInfo As ICONINFO
        Dim x, y As Integer
        ci.cbSize = Marshal.SizeOf(ci)
        If GetCursorInfo(ci) Then
            hicon = CopyIcon(ci.hCursor)
            If GetIconInfo(hicon, icInfo) Then
                x = ci.ptScreenPos.X - CInt(icInfo.xHotspot)
                y = ci.ptScreenPos.Y - CInt(icInfo.yHotspot)
                Return New Point(x, y)
            End If
        End If
        Return Nothing
    End Function


    <StructLayout(LayoutKind.Sequential)>
    Public Structure CURSORINFO
        Public cbSize As Int32
        Public flags As Int32
        Public hCursor As IntPtr
        Public ptScreenPos As Point
    End Structure

    <StructLayout(LayoutKind.Sequential)>
    Public Structure ICONINFO
        Public fIcon As Boolean
        Public xHotspot As Int32
        Public yHotspot As Int32
        Public hbmMask As IntPtr
        Public hbmColor As IntPtr
    End Structure

    Private Sub translateFromMemory(ByteArray As Byte())
        'Dim testImagePath = "./phototest.tif"
        Dim testImagePath = "./page1b.png"

        Try
            Using engine = New TesseractEngine("./tessdata", "eng", EngineMode.Default)
                'Using img = Pix.LoadFromFile(testImagePath)
                Using img = Pix.LoadTiffFromMemory(ByteArray)
                    Using page = engine.Process(img)
                        Dim text = page.GetText()
                        Console.WriteLine("Mean confidence: {0}", page.GetMeanConfidence())

                        Console.WriteLine("Text (GetText): " & vbCr & vbLf & "{0}", text)
                        Console.WriteLine("Text (iterator):")
                        Using iter = page.GetIterator()
                            iter.Begin()

                            Do
                                Do
                                    Do
                                        Do
                                            If iter.IsAtBeginningOf(PageIteratorLevel.Block) Then
                                                Console.WriteLine("<BLOCK>")
                                            End If

                                            TextBox1.Text &= (iter.GetText(PageIteratorLevel.Word))
                                            TextBox1.Text &= (" ")

                                            If iter.IsAtFinalOf(PageIteratorLevel.TextLine, PageIteratorLevel.Word) Then
                                                TextBox1.Text &= vbCrLf
                                            End If
                                        Loop While iter.[Next](PageIteratorLevel.TextLine, PageIteratorLevel.Word)

                                        If iter.IsAtFinalOf(PageIteratorLevel.Para, PageIteratorLevel.TextLine) Then
                                            Console.WriteLine()
                                        End If
                                    Loop While iter.[Next](PageIteratorLevel.Para, PageIteratorLevel.TextLine)
                                Loop While iter.[Next](PageIteratorLevel.Block, PageIteratorLevel.Para)
                            Loop While iter.[Next](PageIteratorLevel.Block)
                        End Using
                    End Using
                End Using
            End Using
        Catch ex As Exception
            Trace.TraceError(ex.ToString())
            Console.WriteLine("Unexpected Error: " + ex.Message)
            Console.WriteLine("Details: ")
            Console.WriteLine(ex.ToString())
        End Try
        Console.Write("Press any key to continue . . . ")

    End Sub

    Private Sub translateFromFile(testImagePath As String, sw As IO.StreamWriter)
        Try
            Using engine = New TesseractEngine("./tessdata", "eng", EngineMode.Default)
                Using img = Pix.LoadFromFile(testImagePath)
                    Using page = engine.Process(img)
                        Dim text = page.GetText()
                        Console.WriteLine("Mean confidence: {0}", page.GetMeanConfidence())

                        Console.WriteLine("Text (GetText): " & vbCr & vbLf & "{0}", text)
                        Console.WriteLine("Text (iterator):")
                        Using iter = page.GetIterator()
                            iter.Begin()

                            Do
                                Do
                                    Do
                                        Do
                                            If iter.IsAtBeginningOf(PageIteratorLevel.Block) Then
                                                Console.WriteLine("<BLOCK>")
                                            End If

                                            'TextBox1.Text &= (iter.GetText(PageIteratorLevel.Word))
                                            'TextBox1.Text &= (" ")
                                            sw.Write(iter.GetText(PageIteratorLevel.Word) & (" "))

                                            If iter.IsAtFinalOf(PageIteratorLevel.TextLine, PageIteratorLevel.Word) Then
                                                sw.WriteLine()
                                            End If
                                        Loop While iter.[Next](PageIteratorLevel.TextLine, PageIteratorLevel.Word)

                                        If iter.IsAtFinalOf(PageIteratorLevel.Para, PageIteratorLevel.TextLine) Then
                                            Console.WriteLine()
                                        End If
                                    Loop While iter.[Next](PageIteratorLevel.Para, PageIteratorLevel.TextLine)
                                Loop While iter.[Next](PageIteratorLevel.Block, PageIteratorLevel.Para)
                            Loop While iter.[Next](PageIteratorLevel.Block)
                        End Using
                    End Using
                End Using
            End Using
        Catch ex As Exception
            Trace.TraceError(ex.ToString())
            Console.WriteLine("Unexpected Error: " + ex.Message)
            Console.WriteLine("Details: ")
            Console.WriteLine(ex.ToString())
        End Try
        Console.Write("Press any key to continue . . . ")
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Timer1.Interval = 1000
        Timer1.Enabled = True
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        If (FolderBrowserDialog1.ShowDialog() = DialogResult.OK) Then
            Using sw As StreamWriter = File.AppendText(FolderBrowserDialog1.SelectedPath & "\Output.txt")
                For Each MyFile As String In IO.Directory.GetFiles(FolderBrowserDialog1.SelectedPath)
                    translateFromFile(MyFile, sw)
                    Application.DoEvents()
                Next
            End Using
        End If
    End Sub
End Class

So, A day or so ago. I was in progress of a server retirement and was required to do some minor investigation as to see who may have been using the server if anyone at all. I found this pretty neat little script that is much like UPTIME to see who may have recently logged into the machine and maybe then I can speak to them to see if it is still needed at all. Now sadly, depending on the server the Event log may roll quickly so all the data you may be looking for (Father back in the past) may not be there but that depends on your environment.

function get-logonhistory{
Param (
 [string]$Computer = (Read-Host Remote computer name),
 [int]$Days = 10
 )
 cls
 $Result = @()
 Write-Host "Gathering Event Logs, this can take awhile..."
 $ELogs = Get-EventLog System -Source Microsoft-Windows-WinLogon -After (Get-Date).AddDays(-$Days) -ComputerName $Computer
 If ($ELogs)
 { Write-Host "Processing..."
 ForEach ($Log in $ELogs)
 { If ($Log.InstanceId -eq 7001)
   { $ET = "Logon"
   }
   ElseIf ($Log.InstanceId -eq 7002)
   { $ET = "Logoff"
   }
   Else
   { Continue
   }
   $Result += New-Object PSObject -Property @{
    Time = $Log.TimeWritten
    'Event Type' = $ET
    User = (New-Object System.Security.Principal.SecurityIdentifier $Log.ReplacementStrings[1]).Translate([System.Security.Principal.NTAccount])
   }
 }
 $Result | Select Time,"Event Type",User | Sort Time -Descending | Out-GridView
 Write-Host "Done."
 }
 Else
 { Write-Host "Problem with $Computer."
 Write-Host "If you see a 'Network Path not found' error, try starting the Remote Registry service on that computer."
 Write-Host "Or there are no logon/logoff events (XP requires auditing be turned on)"
 }
}


get-logonhistory -Computer "RemoteHostName" -Days "30"

WSDL: https://EpicServer/Interconnect-REL-EDI/wcf/Epic.Security.GeneratedServices/PersonnelManagement.svc?wsdl

REQUEST:

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:Epic-com:Security.2014.Services.PersonnelManagement" xmlns:arr="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:urn1="urn:Epic-com:Security.2012.Services.PersonnelManagement">
   <soapenv:Header/>
   <soapenv:Body>
      <urn:CreateUser>
                  <urn:UserInternalID>*</urn:UserInternalID>
                  <urn:Name>Hall, Nicholas A</urn:Name>
                  <urn:ContactDate>T</urn:ContactDate>
                  <urn:ContactComment>Initial Entry</urn:ContactComment>
                  <urn:SystemLoginID>12345</urn:SystemLoginID>
                  <urn:IsActive>0</urn:IsActive>             
                  <urn:UserDictionaryPath>\\epic-files\User_Dictionaries\12345dictionary.tlx</urn:UserDictionaryPath>


         <urn:LinkedTemplatesConfig>
            <urn:AppliedTemplateID>
               <urn1:ID>T1595999</urn1:ID>
               <urn1:Type>external</urn1:Type>
            </urn:AppliedTemplateID>
            <urn:AvailableLinkableTemplates>
               <urn:AvailableTemplateSetup>
                  <urn:LinkedTemplateID>
                     <urn1:ID>T1595999</urn1:ID>
                     <urn1:Type>external</urn1:Type>
                  </urn:LinkedTemplateID>
               </urn:AvailableTemplateSetup>
               <urn:AvailableTemplateSetup>
                  <urn:LinkedTemplateID>
                     <urn1:ID>T2101700303</urn1:ID>
                     <urn1:Type>external</urn1:Type>
                  </urn:LinkedTemplateID>
               </urn:AvailableTemplateSetup>
            </urn:AvailableLinkableTemplates>
            <urn:DefaultTemplateID>
               <urn1:ID>T1595999</urn1:ID>
               <urn1:Type>external</urn1:Type>
            </urn:DefaultTemplateID>
         </urn:LinkedTemplatesConfig>

                  <urn:UserSubtemplateIDs>           
                        <urn1:IndexedRecordIn>
                              <urn1:Identifier>
                                    <urn1:ID>T00063</urn1:ID>
                                    <urn1:Type>external</urn1:Type>
                              </urn1:Identifier>
                              <urn1:Index>1</urn1:Index>
                        </urn1:IndexedRecordIn>
                        <urn1:IndexedRecordIn>
                              <urn1:Identifier>
                                    <urn1:ID>ST5089456</urn1:ID>
                                    <urn1:Type>external</urn1:Type>
                              </urn1:Identifier>
                              <urn1:Index>2</urn1:Index>
                        </urn1:IndexedRecordIn>
                 </urn:UserSubtemplateIDs>



                 <urn:CustomUserDictionaries>
                        <urn1:IndexedString>
                              <urn1:Index>1</urn1:Index>
                              <urn1:Value>\\epic-files\User_Dictionaries\12345Ddictionary.tlx</urn1:Value>
                        </urn1:IndexedString>
                 </urn:CustomUserDictionaries>

        <urn:ExternalIdentifiers>
               <urn1:ExternalIdentifier>
                  <urn1:Identifier>e12345</urn1:Identifier>
                  <urn1:IdentifierType>EMC Mckesson Document Imaging</urn1:IdentifierType>
                  <urn1:IsActive>true</urn1:IsActive>
               </urn1:ExternalIdentifier>
            </urn:ExternalIdentifiers>


      </urn:CreateUser>
   </soapenv:Body>
</soapenv:Envelope>

RESPONSE:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <CreateUserResponse xmlns="urn:Epic-com:Security.2014.Services.PersonnelManagement">
         <CreateUserResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <Messages xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
               <a:string/>
               <a:string/>
               <a:string>User name automatically formatted to HALL, NICHOLAS</a:string>
            </Messages>
            <UserIDs xmlns:a="urn:Epic-com:Security.2012.Services.PersonnelManagement">
               <a:IDType>
                  <a:ID>12131</a:ID>
                  <a:Type>External</a:Type>
               </a:IDType>
               <a:IDType>
                  <a:ID>12131</a:ID>
                  <a:Type>Internal</a:Type>
               </a:IDType>
               <a:IDType>
                  <a:ID>HALL, NICHOLAS</a:ID>
                  <a:Type>Name</a:Type>
               </a:IDType>
               <a:IDType>
                  <a:ID>12345</a:ID>
                  <a:Type>SystemLogin</a:Type>
               </a:IDType>
            </UserIDs>
         </CreateUserResult>
      </CreateUserResponse>
   </s:Body>
</s:Envelope>

REQUEST:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:Epic-com:Security.2014.Services.PersonnelManagement">
   <soapenv:Header/>
   <soapenv:Body>
      <urn:ViewUser>
         <urn:UserID>12345</urn:UserID>
         <urn:UserIDType>SystemLogin</urn:UserIDType>
      </urn:ViewUser>
   </soapenv:Body>
</soapenv:Envelope>

RESPONSE:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <ViewUserResponse xmlns="urn:Epic-com:Security.2014.Services.PersonnelManagement">
         <ViewUserResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <AuthenticationConfigurationID xmlns:a="urn:Epic-com:Security.2012.Services.PersonnelManagement"/>
            <BlockStatus xmlns:a="urn:Epic-com:Security.2012.Services.PersonnelManagement">
               <a:Comment/>
               <a:IsBlocked>false</a:IsBlocked>
               <a:Reason/>
            </BlockStatus>
            <CategoryReportGrouper1 xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
            <CategoryReportGrouper2 xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
            <CategoryReportGrouper3 xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
            <CategoryReportGrouper4 xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
            <CategoryReportGrouper5 xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
            <CategoryReportGrouper6 xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
            <ContactComment>Initial Entry</ContactComment>
            <CustomUserDictionaries xmlns:a="urn:Epic-com:Security.2012.Services.PersonnelManagement">
               <a:IndexedString>
                  <a:Index>1</a:Index>
                  <a:Value>\\Serverfiles\User_Dictionaries\12345Ddictionary.tlx</a:Value>
               </a:IndexedString>
            </CustomUserDictionaries>
            <DefaultLoginDepartmentID xmlns:a="urn:Epic-com:Security.2012.Services.PersonnelManagement"/>
            <EmployeeDemographics/>
            <EndDate i:nil="true"/>
            <ExternalIdentifiers xmlns:a="urn:Epic-com:Security.2012.Services.PersonnelManagement"/>
            <InBasketClassifications xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
            <IsActive>false</IsActive>
            <IsPasswordChangeRequired>false</IsPasswordChangeRequired>
            <LDAPOverrideID/>
            <LinkedProviderID xmlns:a="urn:Epic-com:Security.2012.Services.PersonnelManagement"/>
            <LinkedTemplatesConfig>
               <AppliedTemplateID xmlns:a="urn:Epic-com:Security.2012.Services.PersonnelManagement">
                 ......
               </AppliedTemplateID>
               <AvailableLinkableTemplates>
                  <AvailableTemplateSetupOut>
                     <EndDate/>
                     ......
                     <LoginTypes xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
                     <StartDate/>
                  </AvailableTemplateSetupOut>
               </AvailableLinkableTemplates>
               <DefaultTemplateID xmlns:a="urn:Epic-com:Security.2012.Services.PersonnelManagement">
                  .....
               </DefaultTemplateID>
            </LinkedTemplatesConfig>
            <Name>Nicholas Hall</Name>
            <Notes/>
            <PrimaryManager xmlns:a="urn:Epic-com:Security.2012.Services.PersonnelManagement"/>
            <ProviderAtLoginOption/>
            <ReportGrouper1/>
            <ReportGrouper2/>
            <ReportGrouper3/>
            <Sex/>
            <StartDate i:nil="true"/>
            <UserAlias/>
            <UserComplexName>
               ....
            </UserComplexName>
            ....
            <UsersManagers xmlns:a="urn:Epic-com:Security.2012.Services.PersonnelManagement"/>
         </ViewUserResult>
      </ViewUserResponse>
   </s:Body>
</s:Envelope>

Yesterday, I ended up giving a 90-minute talk in the Certified Ethical Hacker course and found that my colleagues required a little bit from brushing up on the network foundation. In the course of the hour and a half, I noted the following bullet points.

TOPIC: OSI Layers and ARP Poisoning

Things to note on the layers and ARPing.

Yesterday’s talk was the foundation of all Packet spoofing. Once I get my source code ready I’ll send you a copy.

Issues with Electricity / Electromagnetism
1: What is sent may not be received. *Addressed in layer 4 of the OSI if needed
2: What is sent in a specific order may not be received in the order (This is due to us wanting more speed/Larger bandwidth) *Addressed in layer 4 of the OSI if needed
3: What is received may not be from who you think it is. *Addressed in layer 5 of the OSI if needed

Additional features programmers normally want that is assessed in the OSI Model. Is the connection Alive or Broken? Save Money in Infrastructure. Computers to remember previous clients/connections A message orientated protocol vs. a Stream orientated.

Layer1: Physical, Keep the voltage HIGH so you don’t have to send someone out on horseback
Layer2: Addressing so you save cost on infrastructure instead of running multiple lines to the same physical location
Layer3: Routing, To fix issues broadcasting to the whole world and flooding bandwidth.
Layer4: Depending on your choice of Protocol you can resolve Data being sent in a specific order, and also if it even gets there
Layer5: Computer do not remember who they are connected to when the connection is closed, This is normally resolved at this layer along with AUTHENTICATION
Layer6: At this layer, you create your Message delimiter
Layer7: At this layer, you present the outcome to the end user.

ARP: Address Resolution Protocol Send a Normal reply packet to the Victim and replace your IP with the one you would like to highjack. ARP always act’s on the latest packet, so send it to the victim every second. To prevent dropped connections, ARP the other side as well to shut it up!

DHCP: Victim Broadcast on the network for an IP. How do you hack this protocol: BEAT THE ROUTER TO THE PUNCH AND REPLY BACK BEFORE THE ROUTER DOES!

DNS: Arp Poison the Router to intercept the reply back to the victim and update the IP inside the packet to point to where you want the victim to go OR Gain access to the router, Update the DHCP Settings so that there is a Static IP pointing to your DNS Server.

TCP Spoofing without/with ARPING / Layer 2/3 MITM(Man in the Middle) tricks: Can a TCP packet be spoofed? Yes, IF you know the SEQ number from the client in the middle of the transaction (Requires ARP poisoning or Port spanning/mirroring to figure this out, if not GOOD LUCK!) Expect the client may reply back to the correct host and a RST packet will soon follow, The most you can get in is one packet before the connect is disturbed. This is normally around 1460-1550 bytes of data.

What about a spoofing a Net new connection using someone else’s IP address on the network just at the TCP level? No, This is due to the Syn, Syn Ack, Ack handshake that cannot be intercepted at this level and a RST packet will shortly follow, in nature that provides a minor amount of security for TCP indirectly. At this point, ARP poison the host and create a net new TCP connection from there.

Spoof UDP just at layer 4?: Yes, You can spoof this completely to say the data is coming from another client.