bin/SnsAdGroupMembers.dll-Help.xml

<?xml version="1.0" encoding="utf-8"?>
<helpItems schema="maml" xmlns="http://msh">
  <!-- Cmdlet: Invoke-SnsAdGroupMembersManage -->
  <command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
    <command:details>
      <command:name>Invoke-SnsAdGroupMembersManage</command:name>
      <command:verb>Invoke</command:verb>
      <command:noun>SnsAdGroupMembersManage</command:noun>
      <maml:description>
        <maml:para>Invokes Automatic Active Directory Group Membership Management.</maml:para>
      </maml:description>
    </command:details>
    <maml:description>
      <maml:para>Invokes Automatic Active Directory Group Membership Management.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Operation Of "SnsPsAdGroupMembers" PSModule Install It With "AllUsers" Scope. The Idea Behind This Module Is To Be Used On A Scheduled Task "As Service" For The Actual Group Members Management, And Interactively By IT Administrators To Create And Modify The Managed Groups Configuration. This Requires The PSModule To Be Available To Multiple User Accounts.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Creation Of "SnsPsAdGroupMembers" PSModule DataBases, The First Load Of The PSModule Must Be In Elevated Mode. In The Normal Operation The PSModule Does Not Require Elevated Mode. More Information About That Is Provided Further In This Document.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"Why Should I Use This PSModule Instead Of Dynamic Groups?":</maml:para>
      <maml:para>- Well First And Foremost Reason Is Related With The Fact That This PowerShell Module Does Allow To Have Different Logic For Adding And Removing Members. This Is Not Achievable With Dynamic Groups.</maml:para>
      <maml:para>- The Company IT Department Might Need To Use A Single Group For Granting Access Rights In On Premises AD, AzureAD And Use It As Distribution List At The Same Time. Although This Can Be Achieved With Dynamic Groups You Have To Maintain At Least Two Of Them, One For On Premises AD And One For AzureAD.</maml:para>
      <maml:para>- There Are Cases Related With Certain AzureAD Functionalities And Synchronizations With Third Party Cloud Solutions Which Do Not Support Nested And Dynamic Groups. Managing Of Groups With Large Number Of Members In Corporate Environment Without Using Of Group Nestling Could Be Quite Tricky And Related With Lot Of Users Frustration And Administrative Effort.</maml:para>
      <maml:para>- The "SnsPsAdGroupMembers" PSModule Prepare Reports About Modifying Group Members And Audit Of Changes In The Group Management Settings. Whenever A Group Is Used For Granting Sensitive Access Rights Or Managing The Members Of A Sensitive Distribution List, The Group Owners Might Want To Receive Those Reports, Often Immediately After The Above-Mentioned Actions Are Taken.</maml:para>
      <maml:para>- The PSModule Can Be Used Only For Adding Or Only For Removing Members. Using Of Both Is Not Mandatory. This Does Allow Implementation Of Process For Adding Members In Sensitive Groups, Like "Domain Admins" For Example, Following Formal Approval Process, But Removing Members Immediately When The Person Who Owns The Account Leave The Company, Or Change The Position. In This Case There Will Be Zero Tolerance For Users "Forgotten" With More Than Needed Access Rights.</maml:para>
      <maml:para>This PSModule Have The Same Disadvantages And Requirements As The Dynamic Groups. Since The Management Logic Is Based On AD Attribute Values, It Requires The Used Ones To Be Up To Date And Consistent. Some Sort Of Synchronization From The Company HR System Would Address This. Such A Synchronization Is Nice To Have But Not A Requirement. Using My Other PSModule's Will Be Relatively Easy Creation Of Own Synchronization Related With Any On Premises HR Application. Most Of The Cloud Based Ones, Already Have Out Of The Box Synchronization Tools. Creation Of New One Would Not Be Feasible, But It Depends On The API's The Tool Provides.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Manages The Membership Of Active Directory Groups In A Single Domain Forest Based On Predefined Logic About Adding And Removing Members. For That Purpose, The PowerShell Module Uses SQLite Configuration DataBase To Keep Information About:</maml:para>
      <maml:para>- The Managed Groups.</maml:para>
      <maml:para>- The Logic For Adding Members Into Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- The Logic For Removing Members From Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- Explicit Group Inclusions. Those Are AD Objects Which Shall Be Added As Group Members, Although They Do Not Meet The Adding Criteria.</maml:para>
      <maml:para>- Explicit Group Exclusions. Those Are AD Objects Which Shall Not Be Added As Group Members, Although They Do Meet The Adding Criteria.</maml:para>
      <maml:para>- Notification Contacts Who Shall Receive Reports About The Actions And Audit Events Related With Their Own Groups.</maml:para>
      <maml:para>- The PSModule Configuration.</maml:para>
      <maml:para>- Managed Groups Configuration Changes Tracking.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Uses Another SQLite DataBase To Store All The Events Related With The CmdLets Operation And Events Related With Actions Taken On The Managed Groups.</maml:para>
      <maml:para></maml:para>
      <maml:para>To Increase The Confidence In The Automation Among The Group Owners, "SnsPsAdGroupMembers" PSModule Produces Reports Intended To Be Provided To Those Owners, Whenever The PSModule Adds And / Or Removes Members, Whenever It Detects Changes In The Groups Configuration That Might Affect The Group Members, Such Like Changes In The Add Logic, Remove Logic, Explicit Inclusions, Explicit Exclusions And Notification Contacts.</maml:para>
      <maml:para>In Case Of Changes In The Notification Contacts, Both The Old And New Contacts Are Included In The Report Recipients List. The Reports Are Prepared Only When Actual Changes Are Made Or Detected Whenever The Actual Group Management Occur. For That Purpose, The PSModule Uses An SQLite Statistics DataBase To Store Information About:</maml:para>
      <maml:para>- Events Related With Automatic Adding Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Automatic Removing Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Changes In Managed Groups Configuration That Might Affect The Group Membership, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With The Module Operation And Groups Management Intended To Be Provided To The Company IT's. The Internal Events Not Related With Specific Managed Group Are Not Kept In The Statistics DataBase. Therefore The Statistics DataBase Is Not Suitable Source Of Information About Troubleshooting Of Performance, Module Related Issues, And Script Related Issues. However It Is Perfectly Reliable Source Of Troubleshooting Information Related With Troubleshooting Of Incorrect Logic And Any Managed Groups Misconfiguration.</maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Only Prepares Reports And Reverts Them As "SnsReportCollection" Output Object. The Email Relay Options Differ From One Environment To Another, It Is Not Feasible To Maintain Multiple Settings Related With Email Sending In The Configuration DataBase, While Sending Of An Email From PowerShell Is Simple As Running Of A CmdLet. Depending On The Company, Might Be Used Different Languages, Different Wording, Company Branding, Company Stationaries, Company Colors And Company Visual Stylings In The Emails. From That Perspective The PSModule Reverts Reports In Custom Objects And Collections. The User Have To Convert Them To HTML Text And Send Them As Emails, Within The Automation Scripts Which Use "SnsPsAdGroupMembers" Module. The Simplest Way For Doing That Is Using "ConvertTo-Html" And "Send-MailMessage" Native PowerShell CmdLets. Whenever Managed Group Owners Are Not Interested To Receive Any Notifications The Reports For They Own Groups Can Be Disabled Via Leaving Empty The Notification Contacts Setting Of The Group (Or Remove All Notification Contacts For A Managed Group If There Are Already Specified). This Does Not Disable The Logging Of Events Into The Statistics DataBase.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>For DataBase Engine Is Used SQLite. SQLite Is Free Open Source Serverless DataBase, Which Comes With Its Own Advantages And Disadvantages. As Serverless DataBase There Is No Server To Manage The DataBase Requests And Locks. From That Perspective Using A Single SQLite DataBase Either Over Network Or Mapped Drives Or Simultaneously By Multiple Applications / PSSessions Might Lead To Errors In Accessing The DataBase Or DataBase Corruption.</maml:para>
      <maml:para>From That Perspective All The CmdLets Within This Module Have A Feature That Prevents Running Of Those CmdLets In Multiple PowerShell Sessions. All The CmdLets Have Parameter "Force" Which Allows The Usage Of The CmdLets In Multiple PSSessions, Use It At Your Own Risk. The Parameter Is Ignored And Does Not Work When The PSSession Is "As A Service" (In Automation Script Executed With Scheduled Task For Example).</maml:para>
      <maml:para>Both The Configuration And Statistics DataBases Are Located In "C:\ProgramData\SnsAdGroupMembers" By Default. In Order The Folder And DataBase Files To Be Created Properly, The First Run Of This CmdLet To Be Made In Elevated PowerShell Session. Creation Of The DataBase Folder And Setting The Required NTFS Permissions Requires Local Administrator Access Rights. The DataBase Files Can Be Moved / Migrated Into Different Folders, In That Case The Administrator Who Is Doing That Have To Make Sure That The Folder Exists, All The Users That Will Use This PSModule Will Have "Modify" NTFS Permissions Over The Folder And The DataBase Files, Move The DataBase Files Into The New Folder And Properly Provide The Module With The New Folder Absolute (Full) Path.</maml:para>
      <maml:para>Although Using This PSModule On Domain Controllers Is Possible, It Is Against The Best Practices And It Is Not Recommended. All Automations Shall Be Run On Dedicated Virtual Or Physical Machine. From That Perspective It Is Required "Local Admin" Access Rights.</maml:para>
      <maml:para>It Is Not Recommended The DataBase Files To Be Moved, And If That Happen They Shall Be Not Moved On Network Shares Or Mapped Drives. This Will Not Prevent The PSModule To Do Its Job. It Will Introduce Performance Degradation, Possible Interruption In Case Of Network Issues And Eventually Corruption Of The DataBases.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>Never Move DataBases Outside The Default Location When The PSModule Is Installed With Scope "CurrentUser".</maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>"CfgDbFolder" Setting Specifies The Location Of Both Configuration And Statistics DataBases Simultaneously Unless The Statistics DataBase Have Explicitly Specified Location. With Other Words When Modify Configuration DataBase Location And "StatDbFolder" Setting Is Not Used, Both DataBases Have To Be Moved In The New Location.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Contains CmdLets Intended To Be Run Interactively By The User And CmdLets Intended To Be Run Within Automation Scripts On A Schedule As A Service. The CmdLets Intended To Be Used Within Automation Scripts Comply With Additional Requirements Related With Logging, Reporting And Ability To Being Monitored (Using "SnsPsScriptsMonitoring" PSModule For Example). "Invoke-SnsAdGroupMembersManage" Is A CmdLet Intended To Be Used In An Automation Scripts. By Its Nature, This CmdLet Is An Automation Encapsulated Within A CmdLet. The Logs And Events Happening During The CmdLet Run Are Logged In An SQLite DataBase "GroupMembersProvStat.db" Referred Furter As Statistics DataBase. It Could Be Used For Other Reporting Purposes Like Periodical Comprehensive Reports About The Actions Taken By Automation Scripts (This Requires Additional Scripting To Read The DataBase And Prepare The Reports).</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>When Working With Active Directory It Is Important What Identity Attribute Will Be Chosen For Binding To The AD Objects. Although Naturally AD Uses DistinguishedName For Binding And LDAP Queries, It Is Not The Best Possible Identity. The DistinguishedName Is Unique But It Is Not Constant, It Can Be Changed Over The AD Object Life Cycle. An AD Object Can Be Renamed And / Or Moved Into Different Organizational Unit, Or The Organizational Unit Where The Object Is Located Can Be Renamed And / Or Moved. That Will Modify Object's Distinguished Name. In This Case The Active Directory Will Automatically Reflect Those Changes In The Attributes Of The Object And On All Relational Attributes Of The Remaining Objects Which Point To Our Object. For Example "member" Attribute Of All The Groups Where Our AD Object Is Member Of, Or "manager" Attribute Of All Accounts That Our User Is Manager. However AD Will Not Modify Accordingly The PSModule Configuration Stored In An External For The AD DataBase. This Will Lead To Errors And Failures.</maml:para>
      <maml:para>It Is Best Practice The AD Related Applications To Use For Binding Other Identity Attributes Which Do Not Change During The Objects Life Cycle. Those Are "objectGUID" And "objectSid". The Best Practices Gives Preference To The "objectSid" By Various Reasons. Since It Is Possible Groups To Have Member Objects Without "objectSid" (Contact Objects For Example) The "SnsPsAdGroupMembers" PSModule Uses As Identity The "ObjectGUID" Attribute. Thus Way When An Object Is Renamed Or Moved The PSModule Is Not Affected And Continue To Work As Intended.</maml:para>
      <maml:para>The The Well-Known AD Behavior, That When An Object Is Deleted And Then Recreated, All The Access Rights And Group Membership Are Lost, Is Related With The Fact That The Recreated Object Have Different "objectSid". Using The "objectGUID" As Identity Introduces Similar Behavior Of "SnsPsAdGroupMembers". Deletion And Recreation Of An AD Group Object Does Not Automatically Enable It For Automatic Members Management With The Logic Of The Deleted Group.</maml:para>
      <maml:para>The Using "objectGUID" As Identity In The PSModule Configuration Ensures That The PSModule Is Not Affected By Objects Rename Or Objects Move. When A Managed Group, Explicit Inclusion, Explicit Exclusion Is Renamed Or Moved Into Different OU, Their "objectGUID" Remains Intact. And The PSModule Continue To Bind To Those Objects Without Errors. However This Does Introduce Additional Overhead For The CmdLets Intended To Manage The Groups Configuration. When An Object Is Provided To Them They Need To Search For That Object In Active Directory, Enumerate The "objectGUID" Of The Object And Specify The Enumerated Value Into The Configuration DataBase. Since The CmdLets Query AD, That Query Can Be Made Against Multiple Attributes, Which Does Provide Freedom For The User To Use Multitude Of Values When An AD Object Is Provided To A Parameter. Please Refer To Each To The Parameters Sections Of Each CmdLet Help Document.</maml:para>
      <maml:para>When LDAP Queries Are Needed The Things Get More Complicated. The LDAP Queries Work Only With DistinguishedName. When You Need To Query About Reports Of A Person, Or Members Of A Group The AD Expects LDAP Query With DistinguishedName Values. An Example Of Often Use LDAP Query Clause Is:</maml:para>
      <maml:para>"(manager=CN=Jane Smith,CN=Users,DC=contoso,DC=com)"</maml:para>
      <maml:para>If "SnsPsAdGroupMembers" PSModule Keep It As Is Into The Configuration, In Case Of DistinguishedName Change, The Logic Will Revert No Results, Which Might Lead To Removal Of All The Members From The Group. Instead The LDAP Clause Is Stored Like:</maml:para>
      <maml:para>"(manager=00000000-0000-0000-0000-000000000000)"</maml:para>
      <maml:para>This Complicates The PSModule Further, As On The AD Managed Group Configuration Creation / Modification It Have To Evaluate The Specified Parameters, Match Them Using RegEx Pattern About Any Distinguished Names, Bind To The AD Object Using The Matched DistinguishedName, Enumerates The AD Object "objectGUID" And Amend The Matched DistinguishedName With The Enumerated "objectGUID". And Before The Actual AD Managed Group Members Management, It Have To Evaluate The Configuration About "objectGUID" Values Using RegEx Matching, Bind To The AD Object Using The Matched "objectGUID", Enumerate The AD Object DistinguishedName And Amend The "objectGUID" With The Enumerated DistinguishedName. Thus Way Introducing Overhead For The PSModule And For The Domain Controller Which Serves The LDAP Requests.</maml:para>
      <maml:para>To Reduce The Number Of The AD Requests And The Overhead, The PSModule Caches The Attributes Of The Previously Bind To Or Queried About AD Objects, And Consequently Uses The Cache Instead Of Making New AD Requests. The Effectiveness Of The AD Cache Depends On The Similarities In The Configuration Of The Groups.</maml:para>
      <maml:para>The Attributes Modified By The "SnsPsAdGroupMembers" PSModule Like "memberOf" AD Attribute, Are Never Cached. Caching Those Might Lead To False Positive Or Real Errors.</maml:para>
      <maml:para>The Values Of The AD Attributes Without Requirements For Uniqueness Cannot Be Used For Indexing And Searches In The Cache. For Example There Is No Uniqueness Requirement For "cn" Attribute, You Can Have Multiple Objects With The Same "cn" As Long As They Are Located In Different OU's. When A CmdLet Parameter From The PSModule Is Provided With "cn" Value, It Must Make LDAP Search To Enumerate The AD Object, Either To Confirm That The Value Corresponds To An AD Object Or To Throw Error About Multiple Objects. In Case We Have The Specified Value In The Cache It Is Not Certain That There Are No Other Objects With The Same Value In The AD Domain. Whenever We Use AD Attributes With Uniqueness Requirements Like Distinguished Name, For Example Presence Of The Provided Value In The Cache Can Be Safely Assumed As Correct And Unique, In That Case Query Against The AD Domain Is Not Needed. Usage Of Values In Attributes Without Uniqueness Requirements Reduces The Effectiveness Of The AD Cache Feature Further.</maml:para>
      <maml:para>Introducing A Cache In The PSModule Introduces All Generic Disadvantages Related With Caching, Like Cached Outdated Values. The "SnsPsAdGroupMembers" PSModule Keeps The AD Cache In The System Memory. This Does Ensure Maximum Speed For Accessing The Cache, With Negative Impact On The Machine Performance Because Of The Increased Memory Usage. Together With The Feature Which Does Not Allow Usage Of The PSModule In Multiple PSSession (Which Actually Force The Users To Close Their PSSessions Once They Finish Their Job), Ensures Relatively Short Life Span Of The Cached Entries, Thus Way Reducing The Cache Effectiveness But Increasing The Reliability Via Minimizing The Possibility For Issues Related With Outdated Entries.</maml:para>
      <maml:para>Although The Shorter Lifespan Of The Cached Entries Reduces The Possibility For Mistakes, It Does Not Eliminate Them Completely. Mistakes Might Happen Without Corrupted Or Outdated Cached Entry. Let Us Assume We Have A Department Related Group Where Members Are Added Based On Specific Value In The Department AD Attribute And Removed When The Value Is Different. At The Same Time, The Department AD Attribute Is Automatically Synchronized From The Company HR System. In Case Of Department Rebranding The Sync From The HR System Will Modify The Attribute Value Of All Department Members. In That Case All The Department Members Will Be Removed From The Group. This Is Addressed With Introducing Of New Feature Which Prevents Any Members Removal Whenever The Members Enumerated For Removing Are More Than Certain Threshold. The Threshold Is Configurable. The Default Value Is 50%.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" Provides A Feature Intended For Quick Identifying Whether A Group Is Automatically Managed Or Not, Which Is Disabled By Default. It Could Be Very Annoying And Frustrating To Manually Add Or Remove A Member Into A Group And The Automation To Revert The Changes Back Because The Member Does Not Match The Adding Or Match The Removing Criteria For The Automatic Group Members Management. Normally The IT Administrators Would Need To Check In The PS Module Configuration To Verify Whether An AD Group Is Automatically Managed Using The PSModule Before Membership Modification. This Might Lead To Failed Scheduled Tasks Due To Multiple PSSessions With The PSModule Loaded. From That Perspective "SnsPsAdGroupMembers" Stores A Predefined Constant Value In A Predefined AD Attribute Of The AD Managed Groups And Clears The Predefined Constant Value From The Predefined AD Attribute Of The Not Managed Groups. Therefore The Company IT Administrators Just Need To Look At That Attribute Before Manually Add Or Remove Groups Members In An AD Group.</maml:para>
      <maml:para>To Enable This Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet, To Specify An AD Attribute And A Constant Value Which Shall Be Set On The AD Managed Groups. To Disable That Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet To Clear Either The Value Or The AD Attribute Used By This Feature Or Both. When Enabled On A Scheduled Job After Actual Group Management "Invoke-SnsAdGroupMembersManage" Sets The Predefined Constant Value Into The Predefined AD Attribute Of All Enabled AD Managed Groups And Clears The Value From All Not Managed AD Groups. Therefore Once The Feature Is Disabled The User Have To Manually Clear The Value From The AD Attribute Of All The Groups In Case The Feature Was Ever Used. Changing The Attribute Will Not Clear The Value From The Old Attribute.</maml:para>
      <maml:para>NOTE: This Feature Considers As Managed Only The Groups That Are Enabled In The Groups Configuration. Disabling A Group From Automatic Members Management, Even Temporary Will Clear The AD Attribute Used By This Feature, Indicating To The Corporate IT Administrators, That The Group Membership Can Be Managed Manually.</maml:para>
      <maml:para>NOTE: This Feature Can Use Only AD Attributes With Type Of Single Valued String.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>Invoke-SnsAdGroupMembersManage Is Intended To Be Used Both Interactively By A User, To Test A Specific AD Managed Group Configuration, And Within Automation Scripts Run On A Schedule As A Service For Actual AD Managed Groups Members Management.</maml:para>
      <maml:para>NOTE: Please Make Sure That The PowerShell Is Closed, When You Finish With The Work On The Managed AD Groups Configuration. Otherwise Either The Other Users Or Any Automated Task Will Be Prevented From Work With The PSModule.</maml:para>
      <maml:para>NOTE: The Automation Scripts That Use This CmdLet Must Be Run With An Active Directory Service Account Which Must Have Sufficient Access Rights To Add Group Members, Remove Group Members And Modify Active Directory Attributes Of The AD Group Objects. The Same Applies To The Users Who Run The CmdLet Interactively.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In Parameters Validations "Invoke-SnsAdGroupMembersManage" CmdLet Enumerates The AD Managed Group Configuration Objects Corresponding To Any Specified Group Identities. When Value Is Provided To "Identity" Parameter The CmdLet Switches To "WhatIf" Mode Automatically. When Actual Group Members Management Needs To Be Performed, The CmdLet Shall Be Run Without "Identity" Parameter. Thus Way No Groups Will Be Skipped From Members Management, Except The Explicitly Disabled Ones.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "BeginProcessing" Method "Invoke-SnsAdGroupMembersManage" CmdLet Initializes The PSModule Configuration, Verifies The Availability And The Accessibility Of The Active Directory, Verifies The Existence, The Schema And The Integrity Of The Configuration And Statistics DataBases. Imports, Validates, And Normalizes The Managed Groups, Groups Explicit Inclusions, Groups Explicit Exclusions And Groups Notification Contacts Configuration. Those Are Stored In Different DataBase Tables Within The Configuration DataBase.</maml:para>
      <maml:para></maml:para>
      <maml:para>The Verifications And Normalizations Made On "Groups" Configuration Are:</maml:para>
      <maml:para>- Verifies About Invalid Values In Enabled Column And If There Are Any The Are Replaced With Disabled. Because SQLite Does Not Have Native Boolean Type, We Are Using Integers As Representation Of Booleans, Where 0 Is False 1 Is True. Since We Are Using Column With Type Integer It Allows All Integers, Not Just 0 And 1. Therefore In Case Of Manual Intervention Of The DataBase Using GUI Or CLI Tools, The Data Can Be Manipulated To Cause Errors In The Module. Therefore The CmdLet Replaces All Values Which Are Not 0 Or 1 With 0. Using GUI Or CLI Tools To Directly Access The PSModule DataBases Is Not Recommended. Do It At Your Own Risk!!!</maml:para>
      <maml:para>- Deletes All Rows With Missing Data In "GroupGuid" And "GroupCn" Columns Simultaneously.</maml:para>
      <maml:para>- Deletes All Rows With Missing Data In "AddLdapQuery" And "RemoveLdapQuery" Columns Simultaneously. Obviously If We Not Manage The Group Members The Group Is Not Managed And Have No Place In The Managed Groups Configuration.</maml:para>
      <maml:para>- Updates Any Rows With Missing Data In "GroupGuid" Using LDAP Search With The Value In The "GroupCn".</maml:para>
      <maml:para>- Replaces Any DistinguishedName, And SID Values If Any In "AddLdapQuery" Column With The "objectGUID" Of Their Corresponding AD Object.</maml:para>
      <maml:para>- Replaces Any DistinguishedName, And SID Values If Any In "RemoveLdapQuery" Column With The "objectGUID" Of Their Corresponding AD Object.</maml:para>
      <maml:para>- Replaces Any DistinguishedName, And SID Values If Any In "GroupGuid" Column With The "objectGUID" Of Their Corresponding AD Object.</maml:para>
      <maml:para>- Replaces ":Expand:", ":Band", ":Band", ":Bor" And ":Bor" Strings If Present With The Actual LDAP Operator In "AddLdapQuery" And "RemoveLdapQuery" Columns.</maml:para>
      <maml:para>- Deletes Any Entries Without Values In "GroupGuid" Column. All Managed GroupGuid's Should Be Already Enumerated On The Previous Steps.</maml:para>
      <maml:para>- Deletes Any Entries With Values In "GroupGuid" Column Which Does Not Match The GUID Syntax. All DistinguishedName Or SID Values Had To Be Replaced With Their Corresponding Objects "objectGUID" So Far If Their Values Are Correct.</maml:para>
      <maml:para>- Deletes Any Duplicate Entries If There Are Any. Normally The CmdLets Would Not Allow Duplicates, If We Have Such It Is Manual Intervention Directly In The DataBase Using Third Party GUI Or CLI Tools. As I Wrote Above Doing So Is Not Recommended And If You Do, Do It At Your Own Risk.</maml:para>
      <maml:para>- Updates The "GroupCn" Columns With The Actual CN Of The Group. The "GroupCn" Is Used For Reporting, Obviously We Need The Reporting To Work As Expected With The Correct Values Since The Very Beginning. There Might Be Renamed Groups Since The Previous CmdLet Execution. Of Course The Cache Is Used As Well, And If The PSSession Is Kept Started Since Before The Rename The Caching Might Lead To Unexpected Results.</maml:para>
      <maml:para>- Reorder The Managed Groups Positions, In A Way So They Start From 0 And Are Consequent. Because The Pre-Processing Above Might Delete Configuration Entries, Might Lead To Empty Position Numbers. The Group Position Determine The Order In Which The Groups Will Be Managed. Which Might Be Important In Case A Group Logic Uses The Membership Of Another Group.</maml:para>
      <maml:para>It Sounds Not Logical To Manage Group Membership Based On The Membership In Another Group, However Certain Features In Azure Does Not Work With Nested Groups, Such As Granting Azure Roles And Scope Groups For Certain Azure Apps, Like Single Sign On And Provisioning Apps For Third Party Cloud Solutions. Therefore To Achieve The Nesting Effect Without Using Nesting, Management Of Groups Based On The Membership Of Other Groups Is Required. For Example, We Have A Company With Two Branches, Headquarters In New York And Second Site In London. We Have HRs In Both Sites. We Create Two Distribution Lists "New York HRs" And "London HRs" Both Automatically Managed With Very Complex Add And Remove Logics. We Need To Make Another Group "All HRs". Normally We Would Nest The Existing Groups Into The New One. However We Need This Group To Be AADConnect Synced To Azure And Allow Single Sign On To Workday For Example, Whose SSO App Cannot Work With Nested Groups. In That Case Instead To Repeat The Very Complex Logics For The HR Groups Created For Each Site, And Overload The Used Domain Controller, We Can Use More Simplified Add LDAP Query Like:</maml:para>
      <maml:para>(|(memberOf=CN=New York HRs,OU=Groups,DC=contoso,DC=com)(memberOf=CN=London HRs,OU=Groups,DC=contoso,DC=com))</maml:para>
      <maml:para>Remove LDAP Query:</maml:para>
      <maml:para>(&amp;(!(memberOf=CN=New York HRs,OU=Groups,DC=contoso,DC=com))(!(memberOf=CN=London HRs,OU=Groups,DC=contoso,DC=com)))</maml:para>
      <maml:para>By Doing So, We Add To The "All HRs" Group The Direct Members Of "New York HRs" And "London HRs". Here The Groups Processing Order Comes To Place. If The "All HRs" Group Have Less Order Position Than The Other Two Site Related Groups, It Will Get As Input Outdated Info. For Example There Might Be A New HR Which Is Waiting To Be Added In "London HRs" Group. Normally He Will Be Added On The Same CmdLet Run. However He Have To Wait Till The Next CmdLet Run To Be Added To "All HRs" Group, Because It Is Already Processed. If "All HRs" Group Is Processed After The Two Site Related HRs Groups, It Will Have Up To Date Input. Because The User Is Already Added To "London HRs" Group. And The User Will Be Added In The "All HRs" Group In The Same CmdLet Execution.</maml:para>
      <maml:para>Issues With The Order Positions Whenever A Prerequisite Group Have Higher Order Position Than The Evaluated Ones Are Reported With Warning In The Internal Report. While The Cases When A Prerequisite Group Is Not Automatically Managed Are Not Reported. The Reason Is That There Are Certain Cases Where Certain Groups Cannot Be Automated. Because Their Management Requires Procedures To Be Followed Related With Either Approvals Or Documenting Or Requirements For Tickets. In That Cases Such Groups Membership Cannot Be Managed Via This CmdLet. However Those Groups Membership Can Be Used As Input For Other Automated Groups. In That Case, We Do Not Need Warnings In The Reports, That We Can Do Nothing About. For Example We Might Have Requirement To Use Fine-Grained Password Policy, To Enforce Higher Password Length Requirements For The Administrators. The Fine-Grain Policy Can Be Assigned Only On Global Security Groups. Unlike Domain Admins Enterprise Admins And Schema Admins Are Universal Security Groups And Cannot Be Added Into Fine-Grained Policy Directly. Those Groups Membership Might Require Approval Process, And Generally, You Do Not Want To Automate Their Membership. However To Address The Password Length Requirement, Can Be Created Global Security Group "Admin Password Policy" Added To The Fine-Grained Policy And Managed Via This CmdLet, To Add The Members Of The "Enterprise Admins" And "Schema Admins". Yes, Those People Could Remove Them Selves Manually From "Admin Password Policy", But The Automation Jobs Will Add Them Again. Sooner Or Later They Will Stop Removing Themselves, They Cannot Be So Quick As An Automation Job Could Be.</maml:para>
      <maml:para>The CmdLet Can Be Used For Either Adding Members Only Or Removing Members Only Or Both Adding And Removing Members. Managed Groups Configuration Entries Are Deleted When Both Adding And Removing Are Missing. At The End Of The Day, In The Scenario Above, We Might Want, All The Leavers To Be Automatically Removed From "Domain Admins” As Soon As Their Labor Contract Is Ended. In That Case We Can Manage "Domain Admins" Group With Only Removal Logic, Made To Remove All Disabled Accounts. Adding Members To Be Not Automated And Instead To Be Followed An Approval Process. If You Do So With Such An Important Group, Please Make Sure You Have An Account Which Is Not Synchronized From The HR System, Just In Case To Be Able To Recover The AD Domain, If That Sync Become Mad And Disables All The Accounts.</maml:para>
      <maml:para>The Example With The HR Groups Above Shows Another Use Case Scenario When Might Be Needed Group Membership Input For Managing The Membership Of Another Group. As It Is Mentioned The Site Groups Are Distribution Lists Only, While The "All HR's" Is Intended For Granting Access Rights. Nesting OF Distribution Lists Into Security Group Will Not Grant The Access Rights To Their Members. To Use Nesting They Have To Be Converted To Mail-Enabled Security Groups, Something We Actually Might Want To Avoid.</maml:para>
      <maml:para>NOTE: There Are Not Any Checks About Valid Values In "GroupGuid" Column. Normally They Have To Be Populated By The CmdLets For Managing Of The Groups Configuration. In Case AD Group Objects Get Deleted, Their objectGUID Will Be Not Verified In The Preprocessing Stage. Instead It Will Be Verified And Reported Properly When The Group Members Management Is Made. The Purpose Of The Preprocessing Above Is To Ensure Consistent Data For The ProcessRecord Method. Normally Those Pre-Processing Actions Should Do Nothing Because The Configuration Data Is Verified And Created Using The CmdLets. Therefore The Purpose Of Those Pre-Processing Tasks Is To Ensure That In Case Of Manual Intervention On The Configuration Data, The CmdLet Will Do Whatever It Can To Restore The Data Integrity And Reduce The Damage Caused By Messing With The Configuration.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The Verifications And Normalizations Made On "Inclusions" Configuration Are:</maml:para>
      <maml:para>- Verifies About Invalid Values In Enabled Column And If There Are Any The Are Replaced With Disabled.</maml:para>
      <maml:para>- Deletes All Rows With Missing Data In "GroupGuid" And "GroupCn" Columns Simultaneously.</maml:para>
      <maml:para>- Deletes All Rows With Missing Data In "InclusionGuid" And "InclusionCn" Columns Simultaneously.</maml:para>
      <maml:para>- Updates Any Rows With Missing Data In "GroupGuid" Using LDAP Search With The Value In The "GroupCn".</maml:para>
      <maml:para>- Updates Any Rows With Missing Data In "InclusionGuid" Using LDAP Search With The Value In The "InclusionCn".</maml:para>
      <maml:para>- Replaces Any DistinguishedName, And SID Values If Any In "GroupGuid" Column With The "objectGUID" Of Their Corresponding AD Object.</maml:para>
      <maml:para>- Replaces Any DistinguishedName, And SID Values If Any In "InclusionGuid" Column With The "objectGUID" Of Their Corresponding AD Object.</maml:para>
      <maml:para>- Deletes Any Entries Without Values In "GroupGuid" Column. All Managed GroupGuids Had To Be Enumerated So Far.</maml:para>
      <maml:para>- Deletes Any Entries Without Values In "InclusionGuid" Column. All InclusionGuids Had To Be Enumerated So Far.</maml:para>
      <maml:para>- Deletes Any Entries With Values In "GroupGuid" Column Which Does Not Match The GUID Syntax. By Now All DistinguishedName Or SID Values Had To Be Replaced With Their Corresponding Objects "objectGUID" If The Values Are Correct.</maml:para>
      <maml:para>- Deletes Any Entries With Values In "InclusionGuid" Column Which Does Not Match The GUID Syntax. By Now All DistinguishedName Or SID Values Had To Be Replaced With Their Corresponding Objects "objectGUID" If The Values Are Correct.</maml:para>
      <maml:para>- Updates The "GroupCn" Columns With The Actual CN Of The Group. The "GroupCn" Is Used For Reporting.</maml:para>
      <maml:para>- Updates The "InclusionCn" Columns With The Actual CN Of The Group. The "InclusionCn" Is Used For Reporting.</maml:para>
      <maml:para>- Checks And Deletes Any Orphaned Entries.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The Verifications And Normalizations Made On "Exclusions" Configuration Are:</maml:para>
      <maml:para>- Verifies About Invalid Values In Enabled Column And If There Are Any The Are Replaced With Disabled.</maml:para>
      <maml:para>- Deletes All Rows With Missing Data In "GroupGuid" And "GroupCn" Columns Simultaneously.</maml:para>
      <maml:para>- Deletes All Rows With Missing Data In "ExclusionGuid" And "ExclusionCn" Columns Simultaneously.</maml:para>
      <maml:para>- Updates Any Rows With Missing Data In "GroupGuid" Using LDAP Search With The Value In The "GroupCn".</maml:para>
      <maml:para>- Updates Any Rows With Missing Data In "ExclusionGuid" Using LDAP Search With The Value In The "ExclusionCn".</maml:para>
      <maml:para>- Replaces Any DistinguishedName, And SID Values If Any In "GroupGuid" Column With The "objectGUID" Of Their Corresponding AD Object.</maml:para>
      <maml:para>- Replaces Any DistinguishedName, And SID Values If Any In "ExclusionGuid" Column With The "objectGUID" Of Their Corresponding AD Object.</maml:para>
      <maml:para>- Deletes Any Entries Without Values In "GroupGuid" Column. By Now All Managed GroupGuids Had To Be Enumerated.</maml:para>
      <maml:para>- Deletes Any Entries Without Values In "ExclusionGuid" Column. By Now All ExclusionGuids Had To Be Enumerated.</maml:para>
      <maml:para>- Deletes Any Entries With Values In "GroupGuid" Column Which Does Not Match The GUID Syntax. By Now All DistinguishedName Or SID Values Had To Be Replaced With Their Corresponding Objects "objectGUID" If The Values Are Correct.</maml:para>
      <maml:para>- Deletes Any Entries With Values In "ExclusionGuid" Column Which Does Not Match The GUID Syntax. By Now All DistinguishedName Or SID Values Had To Be Replaced With Their Corresponding Objects "objectGUID" If The Values Are Correct.</maml:para>
      <maml:para>- Updates The "GroupCn" Columns With The Actual CN Of The Group. The "GroupCn" Is Used For Reporting.</maml:para>
      <maml:para>- Updates The "ExclusionCn" Columns With The Actual CN Of The Group. The "ExclusionCn" Is Used For Reporting.</maml:para>
      <maml:para>- Checks And Deletes Any Orphaned Entries.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The Verifications And Normalizations Made On "NotificationContacts" Configuration (In The DataBase It Is "Contacts" Table) Are:</maml:para>
      <maml:para>- Verifies About Invalid Values In Enabled Column And If There Are Any The Are Replaced With Disabled.</maml:para>
      <maml:para>- Deletes All Rows With Missing Data In "GroupGuid" And "GroupCn" Columns Simultaneously.</maml:para>
      <maml:para>- Updates Any Rows With Missing Data In "GroupGuid" Using LDAP Search With The Value In The "GroupCn".</maml:para>
      <maml:para>- Replaces Any DistinguishedName, And SID Values If Any In "GroupGuid" Column With The "objectGUID" Of Their Corresponding AD Object.</maml:para>
      <maml:para>- Deletes Any Entries Without Values In "GroupGuid" Column. By Now All Managed GroupGuids Had To Be Enumerated.</maml:para>
      <maml:para>- Deletes Any Entries Without Values In "Email" Column.</maml:para>
      <maml:para>- Deletes Any Entries With Values In "GroupGuid" Column Which Does Not Match The GUID Syntax. By Now All DistinguishedName Or SID Values Had To Be Replaced With Their Corresponding Objects "objectGUID" If The Values Are Correct.</maml:para>
      <maml:para>- Updates The "GroupCn" Columns With The Actual CN Of The Group. The "GroupCn" Is Used For Reporting.</maml:para>
      <maml:para>- Checks And Deletes Any Orphaned Entries.</maml:para>
      <maml:para>NOTE: There Are Not Any Validations Of The Values In "Email" Column. Thus Way As Notification Contacts Can Be Used External For The AD Domain Recipients, For Example Recipients In Other Domains From The Same Forest Or External For The Organization Recipients. The Module Does Not Make Any Remote PSSessions To The On Premises Exchange / Hybrid Exchange Servers, And It Works For A Single Domain. Therefore The Module Cannot Validate Recipients Outside The Domain Where It Works.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>After The Configuration Preprocessing The Configuration DataBase Is Defragmented. Then The Statistics DataBase Path Is Enumerated, DataBase Existence Is Verified And The DataBase Schema Is Validated.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "ProcessRecord" Method "Invoke-SnsAdGroupMembersManage" CmdLet Enumerates The Configuration Entries For Each Group Coming From The Pipeline Or Specified With "Identity" Parameter. If No Groups Are Specified Or Sent Through The Pipeline The CmdLet Enumerates All Enabled Managed Groups Configuration. When Groups Are Either Specified Or Send Via Pipeline, The CmdLet Switch To "WhatIf" Mode. In That Case The "WhatIf" "Add" And "Remove" Events Are Included In The Notification Contacts Report. Normally They Are Not Included Because It Is Report Only Mode And No Membership Is Changed On The Groups. This Was Introduced To Avoid Forwarding Of The Internal Reports To The Group Contacts When Collaborating With Them On The Managed Group Configuration. The Internal Report Contains Events About All Managed Groups Which Is Not OK To Be Forwarded To Contacts Not Related With The Groups. Specifying "WhatIf" When Identity Is Supplied Will Not Revert The Default "WhatIf" Behavior, And "WhatIf" Events Will Remain Included In The Notification Contacts Reports For The Currently Processed Groups.</maml:para>
      <maml:para>As Per The Best Practices The CmdLet Provides The User With Visual Feedback Of The Progress That Is Being Made In A Progress Bar. To Improve The CmdLet Performance That Feedback Is Provided Only Whenever The CmdLet Is Executed In Interactive PSSession. About Even More In Depth Feedback Related With The CmdLet Progress, Please Use "Verbose" Parameter.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>Each Of The Managed Groups Are Processed In A Loop, And The Following Actions Are Performed On Each Of Them:</maml:para>
      <maml:para></maml:para>
      <maml:para>- Creates Or Updates A Provisioning Start Entry In The Statistics DataBase.</maml:para>
      <maml:para></maml:para>
      <maml:para>- Enumerates Managed Group DistinguishedName And Email. Normally At This Stage The Group Is Already Present In The Internal Cache.</maml:para>
      <maml:para></maml:para>
      <maml:para>- Updates The Predefined AD Attribute Of The Managed Group With Predefined Constant String Intended For Easy Recognizing The Automatically Managed From The Manually Managed AD Groups. This Feature Is Disabled By Default. It Can Be Enabled By Defining An AD Attribute And Constant String Using "Set-SnsAdGroupMembersPsModuleSettings" CmdLet.</maml:para>
      <maml:para></maml:para>
      <maml:para>- Verifies Managed Group Explicit Exclusions. Enumerates Each Exclusion Entry DistinguishedName, This Way Verifying The Exclusion Entry Existence. In Case Enumeration Fails The Exclusion Entry Is Not Processed. And This Is Reported To The Group Notification Contacts. In Case The Enumerated Exclusion DistinguishedName Contains Either ",OU=Leavers," Or ",OU=Disabled Users," Or The AD Account Is Disabled, Warnings Are Thrown Accordingly And The Issue Is Reported To The Notification Contacts As Well. In Those Cases The Exclusion Entry Is Processed Which Might Lead To NDR's Reverted To The Senders Who Send Emails To The Managed Group. The Verified Values Are Compared With The Values From The Previous CmdLet Execution And If They Are Changed An Event Is Included Into Notification Contacts Report. Thus Way The Notification Contacts Are Informed That The Exclusions Are Modified Since The Previous CmdLet Execution.</maml:para>
      <maml:para></maml:para>
      <maml:para>- Verifies Managed Group Explicit Inclusions. The Verification Is Made Exactly In The Same Manner Like The Explicit Exclusions.</maml:para>
      <maml:para></maml:para>
      <maml:para>- Verifies Managed Group Notification Contacts. Enumerates The DistinguishedName Of Each Contact Using The Following LDAP Query "(|(mail=[Mail])(proxyAddresses=smtp:[Mail]))" In Case The Distinguished Name Is Not Enumerated No Actions Are Taken. We Need To Preserve The Functionality For External Contacts As Well. In Case The Recipient Is Enumerated The Notification Contact Is Updated With The Value Taken From Recipients "mail" Attribute If It Is Different. Thus Way When A Notification Contact Change Hers / His Email, The Configuration Will Be Updated Automatically With The New Email Address (Of Course If The Best Practices To Leave The Old Address As Secondary For Certain Period Of Time Are Followed). Afterward The Distinguished Name Is Evaluated Whether The Object Is Leaver. The CmdLet Behavior Is Slightly Different Here. Along With The Warning It Includes The Leavers Manager Taken From "manager" Attribute As A Notification Contact. When Changes Are Detected, In Recipients For The Notification Contacts Report Are Included Both The Old And The New Recipients.</maml:para>
      <maml:para></maml:para>
      <maml:para>- Verifies Whether Managed Group "Add" And "Remove" Queries Rely On Other Managed Groups. If There Are Any Dependency Relations, Their Order Position Are Checked And Whenever Prerequisite Groups Are Processed After The Currently Evaluated One, Warnings Are Thrown. This Feature Can Be Disabled Using "Set-SnsAdGroupMembersPsModuleSettings" CmdLet.</maml:para>
      <maml:para></maml:para>
      <maml:para>- Verifies Managed Group "Add" And "Remove" Queries About Direct Binding To An AD Object Using DistinguishedName And Throw Warning. Normally The Inclusions And Exclusions Can Be Achieved With Proper LDAP Query. At The Same Time This Overcomplicate The Query And Creates Additional Overhead On The Used Domain Controller.</maml:para>
      <maml:para>Let's Explain That With An Example. Let's Assume You Need A Group That Will Include Specific Team That Is Managed By A Certain Manager, And You Need To Include A Person Who Reports To A Different Manager. Then Part Of The LDAP Query Would Look Like:</maml:para>
      <maml:para>"(|(manager=CN=John Smith,CN=Users,DC=contoso,DC=com)(distinguishedName=CN=Jane Smith,CN=Users,DC=contoso,DC=com))"</maml:para>
      <maml:para>Please Keep In Mind That The Build In "Users" Is Container, Not OU. The LDAP Query Could Be Furter Really Complicated With Other Requirements Like The Members To Be Active Employes, To Have Mailbox, To Be Not Contingent Workers And etc. This Will Lead All The Requirements To Be Evaluated Multiple Times Because The Query Contains "OR". Using Explicit Inclusion From The LDAP Query Would Be Removed:</maml:para>
      <maml:para>"(distinguishedName=CN=Jane Smith,CN=Users,DC=contoso,DC=com)"</maml:para>
      <maml:para>And The "OR" Operator. This Example Is About One Inclusion, What If The Explicit Inclusions Were 10? The Same Applies About The Exclusions. This Evaluation Cannot Be Disabled.</maml:para>
      <maml:para></maml:para>
      <maml:para>- Enumerates The Current Members Of The Managed Group. The Enumeration Of The Members Happens With LDAP Query.</maml:para>
      <maml:para>Binding To The Managed Group Object And Enumeration Of Its "member" Attribute Value Does Not Work For Groups With Large Number Of Members, Because There Is An AD Limitation About The Number Of Reverted Objects. The Limitation Depends On The AD Functional Level When The First Domain Controller Was Promoted. The Consequent Increase Of The Domain Functional Level Does Not Increase That Limitation. If You Are Interested How To Increase It Research In Internet. The PSModule Overcomes That Limitation Using LDAP Search, Where It Can Managed The Number Of Reverted Objects. This Slows Down The PSModule But There Is No Need To Modify The AD Configuration Partition Using "ADSIEdit".</maml:para>
      <maml:para>NOTE: The LDAP Query Used To Enumerate The Managed Group Members Does Not Consider The Members Of The Nested Groups. Thus Way If An Object Is Member Of A Nested Group And Not Member Of The Managed Group Directly Will Be Considered As Not Member And If Meets The Requirements To Be A Member Will Be Added Later. Using Such An Automation For Group Members Management With The Time Makes Group Nesting Into The Managed Groups Not Feasible, And Sooner Or Later You'll Stop Nesting In The Managed Groups. However Pay Extra Attention When You Create The Remove LDAP Query And Use Nesting, To Avoid The Nested Groups Removal.</maml:para>
      <maml:para>Nesting Is Used To Simplify The Group Members Management And Reduce The Administrative Effort For That. However When You Are Using An Automation There Is Not Any Administrative Effort For The Group Members Management. Not Using Nesting In The Managed Groups Is Rather Related With The Convenience Of The IT's And Simplifying Any Possible Troubleshooting. The Nesting Does Not Affect The PSModule.</maml:para>
      <maml:para></maml:para>
      <maml:para>- Normalizes The "Add" LDAP Query:</maml:para>
      <maml:para>-- In Case There Is No "Add" Query Specified Throws Warning That No Automatic Members Adding Will Be Made. This Feature Can Be Disabled Using "Set-SnsAdGroupMembersPsModuleSettings" CmdLet.</maml:para>
      <maml:para>-- Evaluates The "Add" Query About String Representation Of "objectGUID" Values And Replaces Them With The DistinguishedName Of The Actual AD Objects. In Case An Enumerated "objectGUID" Cannot Be Found In AD, Throws Error That This Object Does Not Exists. Every Error On That Phase Stops Any Further Processing Of The Specific Managed Group Only. In Case The Enumerated AD Object Is Identified As Leaver Or Is Located In "Disabled Users" OU Warnings Are Thrown. They Do Not Prevent The Further Processing Of The Managed Group. The Normalization Is Made In A Loop Until All String Representations Of "objectGUID" Values In The LDAP Query Are Evaluated And Replaced.</maml:para>
      <maml:para>-- Verifies And Reports About Any Changes In The Managed Group "Add" Logic. This Verification Happens After The LDAP Query Normalization And All The "objectGUID" Values Are Already Replaced With Their Corresponding DistinguishedName. In Case An Object Is Renamed Or Moved Into Different OU There Will Be Event Notifying The Notification Contacts About Change In The Add Logic. I Personally Do Not Consider This As False Positive, Rather As Expected Behavior. Moreover Having DistinguishedName Instead Of GUID In The Event Text Makes More Sense For The Notification Contacts.</maml:para>
      <maml:para></maml:para>
      <maml:para>- Enumerates The AD Objects Eligible To Be Added Via LDAP Search Using The Following LDAP Query:</maml:para>
      <maml:para>"(&amp;(objectCategory=person)(objectClass=user)[AddQuery](!(memberOf=[GroupDN])))"</maml:para>
      <maml:para>Thus Way The AD Search Reverts Only User Accounts Who Meet The Adding Criteria And Are Not Direct Members Of The Managed Group. This Ignores Any Nested Group Members And They Are Present In The AD Search Output. The LDAP Query Is Limited To AD User Accounts Only.</maml:para>
      <maml:para>Normally All HR Tools Are Not Aware Of The AD Groups, Therefore The Synchronization Tools Do Not Sync AD Groups From The HR Systems. The Same Applies To The AD Contact Objects, They Are External Recipients And It Is Not Expected To Be Present In The HR Systems. Therefore It Is Better To Add That Kind Of Objects Manually As Group Members, Than Relying On Manually Updated Attributes. Managing Via Automation Of Those Kind Of Group Members Is Pointless. Whenever You Need To Make A Distribution List With All Contact Objects From Specific Supplier Or Customer, Is Better To Use Either One Time Single Liner PowerShell Script To Add Them Initially And Afterward Manage The Group Manually Or Make A Dynamic Distribution Group. Anyway The Contacts Management Would Be Always Manual, Since There Is Not Any Possibility The Required Input To Be Supplied From An External Partner.</maml:para>
      <maml:para></maml:para>
      <maml:para>- In Case The Managed Group Have Explicit Inclusions, And Those Objects Are Not Already Members Of The Managed Group, They Are Added To The List With Eligible Objects That Will Be Added As Members Later. No Additional Verifications Are Made On The Inclusions At This Stage Except Whether They Are Not Already Members Of The Group. If They Are Already Added On Some Previous Execution Of The CmdLet We Do Not Need To Add Them Again And Report False Positives To The Notification Contacts.</maml:para>
      <maml:para></maml:para>
      <maml:para>- In Case The Managed Group Have Explicit Exclusions And Those Exclusions Are Present In The List Of Objects For Adding, They Are Removed From The List. In Case There Are Exclusions Which Are Not Present In The List For Adding, They Are Reported With A Warning. The Purpose Of The Exclusions Feature Is To Not Add As Group Member An Object Who Meets The Adding Criteria. Therefore An Exclusion Who Does Not Meet The Adding Criteria Is Not Needed And Only Increases The Configuration Size, And Creates Overhead For The CmdLet Verifications.</maml:para>
      <maml:para>NOTE: Because The Exclusions Are Managed After The Inclusions. In Case An Administrator Add The Same Object As Inclusion And As Exclusion Simultaneously, The Exclusion Will Take Precedence. It Is Another Topic Why Someone Will Do So. However This Will Not Create Additional Overhead Neither To The CmdLet Nor To AD, Because On The Second Verification Of The Same Object Everything Needed Will Be Already Cached.</maml:para>
      <maml:para></maml:para>
      <maml:para>- Add All The Remaining Objects In The List For Adding As Group Members. On This Action Is Invoked The PowerShell "ShouldProcess" Method To Ask The User For Confirmation. Because The CmdLet Is Intended To Be Run In Automation Scripts The CmdLet Impact Is "Medium", Therefore The CmdLet Does Not Ask For Confirmation By Default. However "ShouldProcess" Does Provides Additional Useful Features Available To The User Automatically, Such As "WhatIf" And Other Functionalities. At The Same Time "Confirm" Parameter Remains Available And The User Might Decide To Use It When Testing Configuration Changes. Sometimes The Adding's That The CmdLet Might Process, Could Be A Lot, Especially When New Managed Group Entry Is Created. From That Perspective Confirmation Is Asked Once For Adding All The Accounts Which Needs To Be Added And Second Time For Removing All The AD Objects Which Needs To Be Removed. I Personally Found It Not Feasible To Be Asked For Confirmation About Each Individual Adding Or Removing.</maml:para>
      <maml:para>Whenever The CmdLet Is Run Against All Managed Groups In "WhatIf" Mode, "WhatIf" Events Are Created For Each Individual Object And Added To The Internal Report. However When The CmdLet Is Called With Identity Specified Those "WhatIf" Events Are Added To The Notification Contacts Report As Well. Which Makes Sense Because Running The CmdLet With Identity Specified Is To Test Specific Managed Group Configuration, And Not Wait All The Groups To Be Processed, Therefore The Notification Contacts Will Receive Those Events, Instead Of Forwarding The Internal Report To The Requestor, Which Might Contain Events Related With Other Groups. Then Remains Only To Ask The Requestor To Confirm Whether The Actions That The CmdLet Would Take Are Correct And Exactly What Was Requested.</maml:para>
      <maml:para></maml:para>
      <maml:para>- Normalizes The Remove LDAP Query:</maml:para>
      <maml:para>-- In Case There Is No Remove Query Specified Throws Warning That No Automatic Members Removal Will Be Made. This Feature Can Be Disabled Using "Set-SnsAdGroupMembersPsModuleSettings" CmdLet.</maml:para>
      <maml:para>-- Evaluates The Remove Query About String Representation Of "objectGUID" Values And Replaces Them With The DistinguishedName Of The Actual AD Objects. In Case An Enumerated "objectGUID" Cannot Be Found In AD, Throws Error That This Object Does Not Exists. Every Error On That Phase Stops Any Further Processing Of The Specific Managed Group Only. In Case The Enumerated AD Object Is Identified As Leaver Warnings Are Thrown. They Do Not Prevent The Further Processing Of The Managed Group. The Normalization Is Made In A Loop Until All String Representations Of "objectGUID" Values In The LDAP Query Are Evaluated.</maml:para>
      <maml:para>-- Verifies And Reports About Any Changes In The Managed Group "Remove" Logic. This Verification Happens After The LDAP Query Normalization And All The "objectGUID" Values Are Already Replaced With Their Corresponding DistinguishedName. In Case An Object Is Renamed Or Moved Into Different OU There Will Be Event Notifying The Notification Contacts About Change In The Remove Logic.</maml:para>
      <maml:para></maml:para>
      <maml:para>- Enumerates The AD Objects Eligible To Be Removed Via LDAP Search Using The Following LDAP Query:</maml:para>
      <maml:para>"(&amp;[RemoveQuery](memberOf=[GroupDn]))"</maml:para>
      <maml:para>Thus Way The AD Search Reverts Only AD Objects Who Meet The Removal Criteria And Are Direct Members Of The Managed Group. This Ignores Any Nested Group Members And They Are Not Present In The AD Search Output. If A Not Managed Group Is Nested In Managed Group, This Does Not Make It Managed. The LDAP Query Is Not Limited To AD User Accounts. You Have To Be Careful With The Remove Query To Not Accidentally Remove The Nested Groups If You Need To Preserve Them.</maml:para>
      <maml:para></maml:para>
      <maml:para>- In Case The Managed Group Have Explicit Inclusions And Those Inclusions Are Present In The List Of Objects For Removal, They Are Removed From The List. In Case There Are Inclusions Which Are Not Present In The List For Removal, They Are Reported With A Warning. The Purpose Of The Inclusions Feature Is To Keep As Group Member An Object Who Meets The Removal Criteria. Therefore An Inclusion Who Does Not Meet The Removal Criteria Is Not Needed And Only Increases The Configuration Size, And Creates Overhead For The CmdLet Verifications. As It Was Written Above, This CmdLet And PSModule Do Allow Different Logic For Add Than The Logic For Removal. The Removal Logic Can Be Specified In A Way To Allow Members To Remain After They No Longer Meet The Adding Criteria, Or Manually Added Objects To Remain As Members. Which Makes Maintaining Of Inclusion List In Those Cases Unnecessary. Let's Clarify This With An Example. We Take The Example With The Two Sites From Above And We Create A Group Named "New York Employees" And "London Employees". Let's Assume That A Person John Smith Moves From New York To London. If We Do The Removal Logic Strict We Can Do It To Remove All The Account Which Are Disabled Or Not Located In New York. But Also We Might Make That Group To Remove Only The Leavers. In That Case When John Smith Relocate To London He Will Be Not Removed From The Group And We Will Have No Need To Maintain Inclusion List For The Group, Just Because John Wants To Remain Member Of "New York Employees". I Would Advise Strict Removal Logic For Distribution Lists Used For Distributing Sensitive Information, And Security Groups Used For Granting Access Rights. About Groups Used For Chit Chat I Would Advise Not So Strict Removal Logic And Remove Only The Leavers.</maml:para>
      <maml:para></maml:para>
      <maml:para>- In Case The Managed Group Have Explicit Exclusions And Those Exclusions Are Not Present In The List With The Objects For Removal, And Are Currently Direct Members Of the Managed Group, They Are Added To The List For Removal.</maml:para>
      <maml:para></maml:para>
      <maml:para>- Remove All The Remaining Objects In The List For Removal From The Group. On This Action Is Invoked The PowerShell "ShouldProcess" Method To Ask The User For Confirmation With The Same Behavior As Adding The Members.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "EndProcessing" Method "Invoke-SnsAdGroupMembersManage" CmdLet:</maml:para>
      <maml:para></maml:para>
      <maml:para>- Queries The Active Directory About Any Groups That Contain The Predefined Value In The Predefined AD Attribute Used For Quick Distinct Of The Automatically Managed AD Groups. In Case A Search Result Group Is Not Enabled Managed Group, The AD Attribute Is Cleared. Therefore When A Group Is No Longer Managed Or Get Disabled, The Group Attribute Will Be Cleared Accordingly, So The Company IT's To Have Up To Date Information. This Action Is Not Performed When The Imported From The Configuration DataBase Group Configuration Is Incomplete, Those Are The Cases When We Supplied Identities To The CmdLet. This Action Is Not Performed When The CmdLet Is Running In "WhatIf" Mode Without Supplying Any Identities To The CmdLet As Well.</maml:para>
      <maml:para></maml:para>
      <maml:para>- Clears The Outdated Entries In The Statistics DataBase. Events With Event Type Processing Are Kept For 2 Months. Events With Type Provisioning Are Kept For 14 Months. The Group Provisioning Entries Are Deleted When There Are No Longer Events Associated With Them. Which Results In: When Nothing Is Made On A Specific Group On That Provisioning Instance, The Group Entry Is Deleted After 2 Months, Otherwise The Group Entry Is Deleted After 14 Months. Normally The Statistics DataBase Will Only Grow With The Time. To Prevent Any Low Disk Space Issues Or Performance Issues With The DataBase File, Outdated Entries Have To Be Deleted. This Deletion Is On DataBase Level Only, No DataBase File Compacting And Defragmentation Is Made, Because With The Statistics DataBase Growth Over The Time, The Defragmentation And Compacting Time Will Grow. This Might Increase With Hours, The Time Required The CmdLet To Complete, Which Is Not Acceptable.</maml:para>
      <maml:para>If You Use A Physical Or Virtual Machine With Slow Disk System, Or You Manage Huge Number Of Groups, Performance Issues Still Might Happen. In That Case I Would Suggest First To Use "Invoke-SnsStatisticsDataBaseDefragmentation" To Compact The DataBase. If Compacting Do Not Help You Can Modify The Thresholds Using "Set-SnsAdGroupMembersPsModuleSettings" CmdLet.</maml:para>
      <maml:para>The Statistics DataBase Defragmentation Locks The DataBase For Prolong Amount Of Time. If Automated Job For Production Group Members Management Is Executed During That Time, It Will Fail. I Would Recommend The Production Group Management Automations To Be Scheduled In A Way, To Allow Daily Or Weekly Maintenance. For Example, The Automation Job About Production Group Members Management To Be Scheduled From Monday To Saturday On Every 2 Hours. And Once Per Week In Sunday Morning To Be Run A Scheduled Task To Compact The Statistics DataBase.</maml:para>
      <maml:para></maml:para>
      <maml:para>- Initializes And Sends To The Pipeline A "SnsReportCollection" Object. It Is Up To The User To Decide Whether The Reports Will Be Sent Over Emails Or Using Other Ways Of Distribution. If Emails Are Chosen What Will Be The Wording Of Those Emails, Any Company Brand Related Stationaries And Stylings, Which Report Columns To Include And Which To Filter. From That Perspective And Because Of The Best Practices, The Output Is Reverted In An Object. Because The CmdLet Produces Multiple Reports, It Reverts Single Object Which Combines The Reports Within Object Properties. The Output Object Have Properties Which Contains Collections Of Report Objects And Properties That Contain Collections Of Other Objects, That Combine Report Collections With Other Information:</maml:para>
      <maml:para>-- "InternalReport" Property. Contains A Collection Of "SnsReport" Objects Intended For The Use Of The Company IT's And The People That Are Responsible For The Automations. Each "SnsReport" Object Have "Name", "Message", "Severity" And "EventType" Properties. The "Name" And "Message" Properties Are Type Of String. The Other Two Properties Are Type Of Enum.</maml:para>
      <maml:para>-- "MissingGroups" Property. Contains A Collection Of "SnsMissingGroup" Objects Intended For The Use Of The People That Are Responsible For The Automations Only. Each "SnsMissingGroup" Object Have "CN", "Mail", "Started" And "LastProcessed" Properties. The "CN" And "Mail" Properties Are Type Of String. The Other Two Properties Are Type Of DateTime, The DateTime Kind Is Accurate So The User To Be Able To Provide The Timing Either In Local Time Or In UTC Correctly. This Report Contains Information About Any Managed Group That Have Been Started And Disappeared During Process. Normally There Should Be Not Any, Because This CmdLet Does Not Leave Uncomplete Groups For The Next Execution. From That Perspective Such Might Appear When The CmdLet Is Interrupted, A Group Is Not Marked As Completed And On The Next Run That Group Is No Longer Present In The Configuration.</maml:para>
      <maml:para>-- "GroupReports" Property. Contains A Collection Of "SnsGroupReport" Objects Intended To Be Sent To The Notification Contacts Of Individual Groups. "SnsGroupReport" Objects Are Initialized Only For The Groups That Have Notification Contacts, And Events Intended To Be Send To Those Contacts Occur During The CmdLet Run. For Example If No Warning And Errors Related With A Group Are Thrown, And No Members Are Modified, The Notification Contacts Report Is Not Needed, Then No Output Object Is Created For That Specific Group. If An Automation Is Run On A Schedule, In Most Of The Cases This Property Will Contain No Reports, Because Changes In Groups Membership Will Happen After Changes In The HR System, Which Does Not Happen Very Often. "SnsGroupReport" Object Have "GroupGuid" With Type Of String, "GroupCn" With Type Of String, "Contacts" With Type Of String Array And "GroupReport" With Type Of SnsReport Array. The "Contacts" Array Contains The SMTP Addresses Of The Recipients That The Specific Report Shall Be Send. The SnsReport Object Is Already Described In The "InternalReport" Section.</maml:para>
      <maml:para>-- "ContactReports" Property. This Is A Dynamic Property Which Generates On Demand When Accessed "SnsContactReport" Collection With Reports Intended To Specific Recipients Using The "GroupReports". Sending Out Emails For Each Individual Group Could Generate Multiple Emails Intended To Single Notification Contact, In The Cases Where A Single Contact Is Set To Multiple Groups. This Property Combines The Events From The Groups Into Reports Intended To A Single Recipient, Thus Way Reducing The Number Of Notifications Send Out.</maml:para>
      <maml:para>-- "ErrorMessage" Property. To Be Able To Complete And Prepare The Required Reports The CmdLet Does Not Throw Terminating Errors. Instead Whenever An Terminating Event Occur The CmdLet Prepare The Report Object, Store The Terminating Event In This Property And Then Exits. Therefore It Could Be Expected That In Case Of Terminating Event All The Events From The Already Processed Groups Will Be Present In The Corresponding Properties Of The Output Object.</maml:para>
    </maml:description>
    <command:syntax>
      <!-- Parameter set: __AllParameterSets -->
      <command:syntaxItem>
        <maml:name>Invoke-SnsAdGroupMembersManage</maml:name>
        <!-- Parameter: DomainController -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>DomainController</maml:name>
          <maml:description>
            <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
            <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
            <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
            <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
            <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
        <!-- Parameter: Force -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>Force</maml:name>
          <maml:description>
            <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
            <maml:para>Works Only When The CmdLet Is Run Interactively.</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
        <!-- Parameter: Identity -->
        <command:parameter required="false" globbing="false" pipelineInput="true (ByValue)" position="named">
          <maml:name>Identity</maml:name>
          <maml:description>
            <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
            <maml:para>When Identity Parameter Is Specified, WhatIf Parameter Will Be Automatically Set To TRUE.</maml:para>
            <maml:para>Any Adding And Removing "WhatIf" Events Will Be Included In The Contacts Report As Well.</maml:para>
            <maml:para>If Omitted The CmdLet Will Run Against All The Managed Groups.</maml:para>
            <maml:para>The Parameter Accepts The Following Values:</maml:para>
            <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
            <maml:para>- objectGUID</maml:para>
            <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
            <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
            <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
            <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
            <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
            <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
            <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
          </maml:description>
          <command:parameterValue required="true">object</command:parameterValue>
          <dev:type>
            <maml:name>System.Object</maml:name>
            <maml:uri />
          </dev:type>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
    <command:parameters>
      <!-- Parameter: Identity -->
      <command:parameter required="false" globbing="false" pipelineInput="true (ByValue)" position="named">
        <maml:name>Identity</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para>When Identity Parameter Is Specified, WhatIf Parameter Will Be Automatically Set To TRUE.</maml:para>
          <maml:para>Any Adding And Removing "WhatIf" Events Will Be Included In The Contacts Report As Well.</maml:para>
          <maml:para>If Omitted The CmdLet Will Run Against All The Managed Groups.</maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
          <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
          <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <!-- Parameter: DomainController -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>DomainController</maml:name>
        <maml:description>
          <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
          <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
          <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
          <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
          <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: Force -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>Force</maml:name>
        <maml:description>
          <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
          <maml:para>Works Only When The CmdLet Is Run Interactively.</maml:para>
        </maml:description>
        <command:parameterValue required="true">SwitchParameter</command:parameterValue>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
    </command:parameters>
    <command:inputTypes>
      <command:inputType>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para>When Identity Parameter Is Specified, WhatIf Parameter Will Be Automatically Set To TRUE.</maml:para>
          <maml:para>Any Adding And Removing "WhatIf" Events Will Be Included In The Contacts Report As Well.</maml:para>
          <maml:para>If Omitted The CmdLet Will Run Against All The Managed Groups.</maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
          <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
          <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
        </maml:description>
      </command:inputType>
    </command:inputTypes>
    <command:returnValues>
      <!-- OutputType: SnsReportCollection -->
      <command:returnValue>
        <dev:type>
          <maml:name>SnsAdGroupMembers.SnsReportCollection</maml:name>
          <maml:uri />
        </dev:type>
      </command:returnValue>
    </command:returnValues>
    <maml:alertSet>
      <maml:title></maml:title>
      <maml:alert>
        <maml:para>AUTHOR: Svetoslav Nedyalkov Savov</maml:para>
        <maml:para>THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK</maml:para>
        <maml:para>OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.</maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
      </maml:alert>
    </maml:alertSet>
    <command:examples>
      <command:example>
        <maml:title>---------- EXAMPLE 1 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsReportCollection]$objReportCollection = Invoke-SnsAdGroupMembersManage -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Manage The Members Of All Managed AD Groups Taken From The PSModule Configuration.</maml:para>
          <maml:para>Additional Progress Information Is Reverted In The Verbose Stream.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 2 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsReportCollection]$objReportCollection = Invoke-SnsAdGroupMembersManage -Verbose -WhatIf;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Report The Actions And Events That The CmdLet Would Normally Do During The Managing The Members Of All Managed AD Groups Taken From The PSModule Configuration, Without Actual Members Management.</maml:para>
          <maml:para>Additional Progress Information Is Reverted In The Verbose Stream.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 3 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsReportCollection]$objReportCollection = Invoke-SnsAdGroupMembersManage -Verbose -Confirm;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Manage The Members Of All Managed AD Groups Taken From The PSModule Configuration With Asking The User For Confirmation Before To Add Members If There Are Any For Adding, And Second Time Before To Remove Members If There Are Any For Removal.</maml:para>
          <maml:para>Additional Progress Information Is Reverted In The Verbose Stream.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 4 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsReportCollection]$objReportCollection = Invoke-SnsAdGroupMembersManage `
-Identity "Finance Department DL" -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Report The Actions And Events That The CmdLet Would Normally Do During The Managing The Members Of The Specified Managed AD Group, Without Actual Members Management. Any "WhatIf" Adding And Removing Events Will Be Included In The Notification Contacts Report.</maml:para>
          <maml:para>Additional Progress Information Is Reverted In The Verbose Stream.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 5 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsReportCollection]$objReportCollection = "Finance Department DL", "Sales Department DL" | `
Invoke-SnsAdGroupMembersManage -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Report The Actions And Events That The CmdLet Would Normally Do During The Managing The Members Of The Sent Via The Pipeline Managed AD Groups, Without Actual Members Management. Any "WhatIf" Adding And Removing Events Will Be Included In The Notification Contacts Report.</maml:para>
          <maml:para>Additional Progress Information Is Reverted In The Verbose Stream.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
    </command:examples>
    <maml:relatedLinks>
      <maml:navigationLink>
        <maml:linkText> svesavov / SnsPsAdGroupMembers - </maml:linkText>
        <maml:uri>https://github.com/svesavov/SnsPsAdGroupMembers</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> PowerShell Gallery - </maml:linkText>
        <maml:uri>https://www.powershellgallery.com/packages/SnsPsAdGroupMembers/</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> Svetoslav Savov on LinkedIn - </maml:linkText>
        <maml:uri>https://www.linkedin.com/in/svetoslavsavov</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> SQLite V3 - </maml:linkText>
        <maml:uri>https://sqlite.org/index.html</maml:uri>
      </maml:navigationLink>
    </maml:relatedLinks>
  </command:command>
  <!-- Cmdlet: Get-SnsAdGroupMembersPsModuleSettings -->
  <command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
    <command:details>
      <command:name>Get-SnsAdGroupMembersPsModuleSettings</command:name>
      <command:verb>Get</command:verb>
      <command:noun>SnsAdGroupMembersPsModuleSettings</command:noun>
      <maml:description>
        <maml:para>Enumerates "SnsPsAdGroupMembers" PSModule Configuration.</maml:para>
      </maml:description>
    </command:details>
    <maml:description>
      <maml:para>Enumerates "SnsPsAdGroupMembers" PSModule Configuration.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Operation Of "SnsPsAdGroupMembers" PSModule Install It With "AllUsers" Scope. The Idea Behind This Module Is To Be Used On A Scheduled Task "As Service" For The Actual Group Members Management, And Interactively By IT Administrators To Create And Modify The Managed Groups Configuration. This Requires The PSModule To Be Available To Multiple User Accounts.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Creation Of "SnsPsAdGroupMembers" PSModule DataBases, The First Load Of The PSModule Must Be In Elevated Mode. In The Normal Operation The PSModule Does Not Require Elevated Mode. More Information About That Is Provided Further In This Document.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"Why Should I Use This PSModule Instead Of Dynamic Groups?":</maml:para>
      <maml:para>- Well First And Foremost Reason Is Related With The Fact That This PowerShell Module Does Allow To Have Different Logic For Adding And Removing Members. This Is Not Achievable With Dynamic Groups.</maml:para>
      <maml:para>- The Company IT Department Might Need To Use A Single Group For Granting Access Rights In On Premises AD, AzureAD And Use It As Distribution List At The Same Time. Although This Can Be Achieved With Dynamic Groups You Have To Maintain At Least Two Of Them, One For On Premises AD And One For AzureAD.</maml:para>
      <maml:para>- There Are Cases Related With Certain AzureAD Functionalities And Synchronizations With Third Party Cloud Solutions Which Do Not Support Nested And Dynamic Groups. Managing Of Groups With Large Number Of Members In Corporate Environment Without Using Of Group Nestling Could Be Quite Tricky And Related With Lot Of Users Frustration And Administrative Effort.</maml:para>
      <maml:para>- The "SnsPsAdGroupMembers" PSModule Prepare Reports About Modifying Group Members And Audit Of Changes In The Group Management Settings. Whenever A Group Is Used For Granting Sensitive Access Rights Or Managing The Members Of A Sensitive Distribution List, The Group Owners Might Want To Receive Those Reports, Often Immediately After The Above-Mentioned Actions Are Taken.</maml:para>
      <maml:para>- The PSModule Can Be Used Only For Adding Or Only For Removing Members. Using Of Both Is Not Mandatory. This Does Allow Implementation Of Process For Adding Members In Sensitive Groups, Like "Domain Admins" For Example, Following Formal Approval Process, But Removing Members Immediately When The Person Who Owns The Account Leave The Company, Or Change The Position. In This Case There Will Be Zero Tolerance For Users "Forgotten" With More Than Needed Access Rights.</maml:para>
      <maml:para>This PSModule Have The Same Disadvantages And Requirements As The Dynamic Groups. Since The Management Logic Is Based On AD Attribute Values, It Requires The Used Ones To Be Up To Date And Consistent. Some Sort Of Synchronization From The Company HR System Would Address This. Such A Synchronization Is Nice To Have But Not A Requirement. Using My Other PSModule's Will Be Relatively Easy Creation Of Own Synchronization Related With Any On Premises HR Application. Most Of The Cloud Based Ones, Already Have Out Of The Box Synchronization Tools. Creation Of New One Would Not Be Feasible, But It Depends On The API's The Tool Provides.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Manages The Membership Of Active Directory Groups In A Single Domain Forest Based On Predefined Logic About Adding And Removing Members. For That Purpose, The PowerShell Module Uses SQLite Configuration DataBase To Keep Information About:</maml:para>
      <maml:para>- The Managed Groups.</maml:para>
      <maml:para>- The Logic For Adding Members Into Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- The Logic For Removing Members From Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- Explicit Group Inclusions. Those Are AD Objects Which Shall Be Added As Group Members, Although They Do Not Meet The Adding Criteria.</maml:para>
      <maml:para>- Explicit Group Exclusions. Those Are AD Objects Which Shall Not Be Added As Group Members, Although They Do Meet The Adding Criteria.</maml:para>
      <maml:para>- Notification Contacts Who Shall Receive Reports About The Actions And Audit Events Related With Their Own Groups.</maml:para>
      <maml:para>- The PSModule Configuration.</maml:para>
      <maml:para>- Managed Groups Configuration Changes Tracking.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Uses Another SQLite DataBase To Store All The Events Related With The CmdLets Operation And Events Related With Actions Taken On The Managed Groups.</maml:para>
      <maml:para></maml:para>
      <maml:para>To Increase The Confidence In The Automation Among The Group Owners, "SnsPsAdGroupMembers" PSModule Produces Reports Intended To Be Provided To Those Owners, Whenever The PSModule Adds And / Or Removes Members, Whenever It Detects Changes In The Groups Configuration That Might Affect The Group Members, Such Like Changes In The Add Logic, Remove Logic, Explicit Inclusions, Explicit Exclusions And Notification Contacts.</maml:para>
      <maml:para>In Case Of Changes In The Notification Contacts, Both The Old And New Contacts Are Included In The Report Recipients List. The Reports Are Prepared Only When Actual Changes Are Made Or Detected Whenever The Actual Group Management Occur. For That Purpose, The PSModule Uses An SQLite Statistics DataBase To Store Information About:</maml:para>
      <maml:para>- Events Related With Automatic Adding Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Automatic Removing Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Changes In Managed Groups Configuration That Might Affect The Group Membership, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With The Module Operation And Groups Management Intended To Be Provided To The Company IT's. The Internal Events Not Related With Specific Managed Group Are Not Kept In The Statistics DataBase. Therefore The Statistics DataBase Is Not Suitable Source Of Information About Troubleshooting Of Performance, Module Related Issues, And Script Related Issues. However It Is Perfectly Reliable Source Of Troubleshooting Information Related With Troubleshooting Of Incorrect Logic And Any Managed Groups Misconfiguration.</maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Only Prepares Reports And Reverts Them As "SnsReportCollection" Output Object. The Email Relay Options Differ From One Environment To Another, It Is Not Feasible To Maintain Multiple Settings Related With Email Sending In The Configuration DataBase, While Sending Of An Email From PowerShell Is Simple As Running Of A CmdLet. Depending On The Company, Might Be Used Different Languages, Different Wording, Company Branding, Company Stationaries, Company Colors And Company Visual Stylings In The Emails. From That Perspective The PSModule Reverts Reports In Custom Objects And Collections. The User Have To Convert Them To HTML Text And Send Them As Emails, Within The Automation Scripts Which Use "SnsPsAdGroupMembers" Module. The Simplest Way For Doing That Is Using "ConvertTo-Html" And "Send-MailMessage" Native PowerShell CmdLets. Whenever Managed Group Owners Are Not Interested To Receive Any Notifications The Reports For They Own Groups Can Be Disabled Via Leaving Empty The Notification Contacts Setting Of The Group (Or Remove All Notification Contacts For A Managed Group If There Are Already Specified). This Does Not Disable The Logging Of Events Into The Statistics DataBase.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>For DataBase Engine Is Used SQLite. SQLite Is Free Open Source Serverless DataBase, Which Comes With Its Own Advantages And Disadvantages. As Serverless DataBase There Is No Server To Manage The DataBase Requests And Locks. From That Perspective Using A Single SQLite DataBase Either Over Network Or Mapped Drives Or Simultaneously By Multiple Applications / PSSessions Might Lead To Errors In Accessing The DataBase Or DataBase Corruption.</maml:para>
      <maml:para>From That Perspective All The CmdLets Within This Module Have A Feature That Prevents Running Of Those CmdLets In Multiple PowerShell Sessions. All The CmdLets Have Parameter "Force" Which Allows The Usage Of The CmdLets In Multiple PSSessions, Use It At Your Own Risk. The Parameter Is Ignored And Does Not Work When The PSSession Is "As A Service" (In Automation Script Executed With Scheduled Task For Example).</maml:para>
      <maml:para>Both The Configuration And Statistics DataBases Are Located In "C:\ProgramData\SnsAdGroupMembers" By Default. In Order The Folder And DataBase Files To Be Created Properly, The First Run Of This CmdLet To Be Made In Elevated PowerShell Session. Creation Of The DataBase Folder And Setting The Required NTFS Permissions Requires Local Administrator Access Rights. The DataBase Files Can Be Moved / Migrated Into Different Folders, In That Case The Administrator Who Is Doing That Have To Make Sure That The Folder Exists, All The Users That Will Use This PSModule Will Have "Modify" NTFS Permissions Over The Folder And The DataBase Files, Move The DataBase Files Into The New Folder And Properly Provide The Module With The New Folder Absolute (Full) Path.</maml:para>
      <maml:para>Although Using This PSModule On Domain Controllers Is Possible, It Is Against The Best Practices And It Is Not Recommended. All Automations Shall Be Run On Dedicated Virtual Or Physical Machine. From That Perspective It Is Required "Local Admin" Access Rights.</maml:para>
      <maml:para>It Is Not Recommended The DataBase Files To Be Moved, And If That Happen They Shall Be Not Moved On Network Shares Or Mapped Drives. This Will Not Prevent The PSModule To Do Its Job. It Will Introduce Performance Degradation, Possible Interruption In Case Of Network Issues And Eventually Corruption Of The DataBases.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>Never Move DataBases Outside The Default Location When The PSModule Is Installed With Scope "CurrentUser".</maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>"CfgDbFolder" Setting Specifies The Location Of Both Configuration And Statistics DataBases Simultaneously Unless The Statistics DataBase Have Explicitly Specified Location. With Other Words When Modify Configuration DataBase Location And "StatDbFolder" Setting Is Not Used, Both DataBases Have To Be Moved In The New Location.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Contains CmdLets Intended To Be Run Interactively By The User And CmdLets Intended To Be Run Within Automation Scripts On A Schedule As A Service. The CmdLets Intended To Be Used Within Automation Scripts Comply With Additional Requirements Related With Logging, Reporting And Ability To Being Monitored (Using "SnsPsScriptsMonitoring" PSModule For Example). "Invoke-SnsAdGroupMembersManage" Is A CmdLet Intended To Be Used In An Automation Scripts. By Its Nature, This CmdLet Is An Automation Encapsulated Within A CmdLet. The Logs And Events Happening During The CmdLet Run Are Logged In An SQLite DataBase "GroupMembersProvStat.db" Referred Furter As Statistics DataBase. It Could Be Used For Other Reporting Purposes Like Periodical Comprehensive Reports About The Actions Taken By Automation Scripts (This Requires Additional Scripting To Read The DataBase And Prepare The Reports).</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>When Working With Active Directory It Is Important What Identity Attribute Will Be Chosen For Binding To The AD Objects. Although Naturally AD Uses DistinguishedName For Binding And LDAP Queries, It Is Not The Best Possible Identity. The DistinguishedName Is Unique But It Is Not Constant, It Can Be Changed Over The AD Object Life Cycle. An AD Object Can Be Renamed And / Or Moved Into Different Organizational Unit, Or The Organizational Unit Where The Object Is Located Can Be Renamed And / Or Moved. That Will Modify Object's Distinguished Name. In This Case The Active Directory Will Automatically Reflect Those Changes In The Attributes Of The Object And On All Relational Attributes Of The Remaining Objects Which Point To Our Object. For Example "member" Attribute Of All The Groups Where Our AD Object Is Member Of, Or "manager" Attribute Of All Accounts That Our User Is Manager. However AD Will Not Modify Accordingly The PSModule Configuration Stored In An External For The AD DataBase. This Will Lead To Errors And Failures.</maml:para>
      <maml:para>It Is Best Practice The AD Related Applications To Use For Binding Other Identity Attributes Which Do Not Change During The Objects Life Cycle. Those Are "objectGUID" And "objectSid". The Best Practices Gives Preference To The "objectSid" By Various Reasons. Since It Is Possible Groups To Have Member Objects Without "objectSid" (Contact Objects For Example) The "SnsPsAdGroupMembers" PSModule Uses As Identity The "ObjectGUID" Attribute. Thus Way When An Object Is Renamed Or Moved The PSModule Is Not Affected And Continue To Work As Intended.</maml:para>
      <maml:para>The The Well-Known AD Behavior, That When An Object Is Deleted And Then Recreated, All The Access Rights And Group Membership Are Lost, Is Related With The Fact That The Recreated Object Have Different "objectSid". Using The "objectGUID" As Identity Introduces Similar Behavior Of "SnsPsAdGroupMembers". Deletion And Recreation Of An AD Group Object Does Not Automatically Enable It For Automatic Members Management With The Logic Of The Deleted Group.</maml:para>
      <maml:para>The Using "objectGUID" As Identity In The PSModule Configuration Ensures That The PSModule Is Not Affected By Objects Rename Or Objects Move. When A Managed Group, Explicit Inclusion, Explicit Exclusion Is Renamed Or Moved Into Different OU, Their "objectGUID" Remains Intact. And The PSModule Continue To Bind To Those Objects Without Errors. However This Does Introduce Additional Overhead For The CmdLets Intended To Manage The Groups Configuration. When An Object Is Provided To Them They Need To Search For That Object In Active Directory, Enumerate The "objectGUID" Of The Object And Specify The Enumerated Value Into The Configuration DataBase. Since The CmdLets Query AD, That Query Can Be Made Against Multiple Attributes, Which Does Provide Freedom For The User To Use Multitude Of Values When An AD Object Is Provided To A Parameter. Please Refer To Each To The Parameters Sections Of Each CmdLet Help Document.</maml:para>
      <maml:para>When LDAP Queries Are Needed The Things Get More Complicated. The LDAP Queries Work Only With DistinguishedName. When You Need To Query About Reports Of A Person, Or Members Of A Group The AD Expects LDAP Query With DistinguishedName Values. An Example Of Often Use LDAP Query Clause Is:</maml:para>
      <maml:para>"(manager=CN=Jane Smith,CN=Users,DC=contoso,DC=com)"</maml:para>
      <maml:para>If "SnsPsAdGroupMembers" PSModule Keep It As Is Into The Configuration, In Case Of DistinguishedName Change, The Logic Will Revert No Results, Which Might Lead To Removal Of All The Members From The Group. Instead The LDAP Clause Is Stored Like:</maml:para>
      <maml:para>"(manager=00000000-0000-0000-0000-000000000000)"</maml:para>
      <maml:para>This Complicates The PSModule Further, As On The AD Managed Group Configuration Creation / Modification It Have To Evaluate The Specified Parameters, Match Them Using RegEx Pattern About Any Distinguished Names, Bind To The AD Object Using The Matched DistinguishedName, Enumerates The AD Object "objectGUID" And Amend The Matched DistinguishedName With The Enumerated "objectGUID". And Before The Actual AD Managed Group Members Management, It Have To Evaluate The Configuration About "objectGUID" Values Using RegEx Matching, Bind To The AD Object Using The Matched "objectGUID", Enumerate The AD Object DistinguishedName And Amend The "objectGUID" With The Enumerated DistinguishedName. Thus Way Introducing Overhead For The PSModule And For The Domain Controller Which Serves The LDAP Requests.</maml:para>
      <maml:para>To Reduce The Number Of The AD Requests And The Overhead, The PSModule Caches The Attributes Of The Previously Bind To Or Queried About AD Objects, And Consequently Uses The Cache Instead Of Making New AD Requests. The Effectiveness Of The AD Cache Depends On The Similarities In The Configuration Of The Groups.</maml:para>
      <maml:para>The Attributes Modified By The "SnsPsAdGroupMembers" PSModule Like "memberOf" AD Attribute, Are Never Cached. Caching Those Might Lead To False Positive Or Real Errors.</maml:para>
      <maml:para>The Values Of The AD Attributes Without Requirements For Uniqueness Cannot Be Used For Indexing And Searches In The Cache. For Example There Is No Uniqueness Requirement For "cn" Attribute, You Can Have Multiple Objects With The Same "cn" As Long As They Are Located In Different OU's. When A CmdLet Parameter From The PSModule Is Provided With "cn" Value, It Must Make LDAP Search To Enumerate The AD Object, Either To Confirm That The Value Corresponds To An AD Object Or To Throw Error About Multiple Objects. In Case We Have The Specified Value In The Cache It Is Not Certain That There Are No Other Objects With The Same Value In The AD Domain. Whenever We Use AD Attributes With Uniqueness Requirements Like Distinguished Name, For Example Presence Of The Provided Value In The Cache Can Be Safely Assumed As Correct And Unique, In That Case Query Against The AD Domain Is Not Needed. Usage Of Values In Attributes Without Uniqueness Requirements Reduces The Effectiveness Of The AD Cache Feature Further.</maml:para>
      <maml:para>Introducing A Cache In The PSModule Introduces All Generic Disadvantages Related With Caching, Like Cached Outdated Values. The "SnsPsAdGroupMembers" PSModule Keeps The AD Cache In The System Memory. This Does Ensure Maximum Speed For Accessing The Cache, With Negative Impact On The Machine Performance Because Of The Increased Memory Usage. Together With The Feature Which Does Not Allow Usage Of The PSModule In Multiple PSSession (Which Actually Force The Users To Close Their PSSessions Once They Finish Their Job), Ensures Relatively Short Life Span Of The Cached Entries, Thus Way Reducing The Cache Effectiveness But Increasing The Reliability Via Minimizing The Possibility For Issues Related With Outdated Entries.</maml:para>
      <maml:para>Although The Shorter Lifespan Of The Cached Entries Reduces The Possibility For Mistakes, It Does Not Eliminate Them Completely. Mistakes Might Happen Without Corrupted Or Outdated Cached Entry. Let Us Assume We Have A Department Related Group Where Members Are Added Based On Specific Value In The Department AD Attribute And Removed When The Value Is Different. At The Same Time, The Department AD Attribute Is Automatically Synchronized From The Company HR System. In Case Of Department Rebranding The Sync From The HR System Will Modify The Attribute Value Of All Department Members. In That Case All The Department Members Will Be Removed From The Group. This Is Addressed With Introducing Of New Feature Which Prevents Any Members Removal Whenever The Members Enumerated For Removing Are More Than Certain Threshold. The Threshold Is Configurable. The Default Value Is 50%.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" Provides A Feature Intended For Quick Identifying Whether A Group Is Automatically Managed Or Not, Which Is Disabled By Default. It Could Be Very Annoying And Frustrating To Manually Add Or Remove A Member Into A Group And The Automation To Revert The Changes Back Because The Member Does Not Match The Adding Or Match The Removing Criteria For The Automatic Group Members Management. Normally The IT Administrators Would Need To Check In The PS Module Configuration To Verify Whether An AD Group Is Automatically Managed Using The PSModule Before Membership Modification. This Might Lead To Failed Scheduled Tasks Due To Multiple PSSessions With The PSModule Loaded. From That Perspective "SnsPsAdGroupMembers" Stores A Predefined Constant Value In A Predefined AD Attribute Of The AD Managed Groups And Clears The Predefined Constant Value From The Predefined AD Attribute Of The Not Managed Groups. Therefore The Company IT Administrators Just Need To Look At That Attribute Before Manually Add Or Remove Groups Members In An AD Group.</maml:para>
      <maml:para>To Enable This Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet, To Specify An AD Attribute And A Constant Value Which Shall Be Set On The AD Managed Groups. To Disable That Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet To Clear Either The Value Or The AD Attribute Used By This Feature Or Both. When Enabled On A Scheduled Job After Actual Group Management "Invoke-SnsAdGroupMembersManage" Sets The Predefined Constant Value Into The Predefined AD Attribute Of All Enabled AD Managed Groups And Clears The Value From All Not Managed AD Groups. Therefore Once The Feature Is Disabled The User Have To Manually Clear The Value From The AD Attribute Of All The Groups In Case The Feature Was Ever Used. Changing The Attribute Will Not Clear The Value From The Old Attribute.</maml:para>
      <maml:para>NOTE: This Feature Considers As Managed Only The Groups That Are Enabled In The Groups Configuration. Disabling A Group From Automatic Members Management, Even Temporary Will Clear The AD Attribute Used By This Feature, Indicating To The Corporate IT Administrators, That The Group Membership Can Be Managed Manually.</maml:para>
      <maml:para>NOTE: This Feature Can Use Only AD Attributes With Type Of Single Valued String.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>Get-SnsAdGroupMembersPsModuleSettings Is Intended To Be Used Interactively By A User To Retrieve The PSModule Configuration From The Configuration DataBase.</maml:para>
      <maml:para>NOTE: Please Make Sure That The PowerShell Is Closed, When You Finish With The Work On The Managed AD Groups Configuration. Otherwise Either The Other Users Or Any Automated Task Will Be Prevented From Work With The PSModule.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "BeginProcessing" Method "Get-SnsAdManagedGroup" CmdLet Initializes The PSModule Configuration. Verifies The Existence, The Schema And The Integrity Of The Configuration DataBase. Verifies About Other PowerShell Processes Using "SnsPsAdGroupMembers" PSModule. Then Sends Out The PSModule Configuration Object.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The CmdLet Reverts SnsPsModuleSetting Object With The Following Properties:</maml:para>
      <maml:para>- "AutomationManagedAttribute" Property Of Type String. Represents The AD Attribute Name As It Is Seen In Attributes Tab Of "Active Directory Users and Computers" Management Console, Used To Indicate Whether Or Not An AD Group Is Automatically Managed. Whenever The Property Have No Value The Feature Is Disabled.</maml:para>
      <maml:para>- "AutomationManagedValue" Property Of Type String. Represents The Value Which The PSModule Put In "AutomationManagedAttribute" To Indicate Whether Or Not An AD Group Is Automatically Managed. Whenever The Property Have No Value The Feature Is Disabled.</maml:para>
      <maml:para>- "BlockRemovalPercent" Property Of Type Int32. Contains The Threshold In Percent About Block Automated Group Members Removal. In Case Of Organization Changes Or Other Reason, After The AD Accounts Synchronization From An HR System, It Might Happen That All The Members Of An Automated Group Match The Removal Logic. To Prevent The Removal Of All The Members From A Group "SnsPsAdGroupMembers" PSModule Evaluate The Number Of The Current Members, The Members Evaluated For Removal And Calculates Removal Percentage. In case The Removal Percentage Is Bigger Than The Value Specified In This Parameter, No Members Are Removed And The Issue Is Reported.</maml:para>
      <maml:para>- "VerifyLeaversAccountDisabled" Property Of Type Boolean. Indicates Whether The AD Managed Group Configuration Is Verified About Bindings To Disabled AD Accounts. Disabling This Verification Will Stop The Events Generation When Either Group Notification Contact Or Exclusion Or Inclusion User Leave The Company And His / Hers AD Account Get Disabled On All AD Managed Groups. In That Case An IT Administrator Should Regularly Check The AD Managed Groups Configuration. To Prevent False Positive Report Events, This Verification Have To Be Disabled Whenever Either Notification Contacts Or Inclusions Or Exclusions Or AddLogic Or RemoveLogic Contains Shared Mailboxes.</maml:para>
      <maml:para>- "VerifyLeaversOu" Property Of Type String Array. Contains An Array With DistinguishedName Parts Of The Organizational Units Where The Leavers Accounts Are Kept. According To The Best Practices, When A User Leave The Company, The AD Account Is Kept Disabled For Certain Period Of Time. Whenever The Process Include Moving The Leavers Accounts To A Dedicated OU This Features Comes In Handy. The PSModule Verifies The Groups Configuration About Bindings To AD Accounts Located In Those OU's, And Report That. This Is Very Useful Whenever "VerifyLeaversAccountDisabled" Feature Is Disabled. To Disable This Feature Assign Empty Array.</maml:para>
      <maml:para>- "ReportPositionIssuesWithPrerequisiteGroups" Property Of Type Boolean. Indicates Whether The AD Managed Group Configuration Is Verified About AD Managed Groups Used As Input In Other AD Managed Groups Logic, And Whether The Prerequisite Group Is Managed After The Dependent One. When The Prerequisite Group Is Managed Beforehand, On The Dependent Group Management Will Have Up To Date Input. Otherwise The Dependent Group Will Be Updated Accordingly Earliest On The Next Management Schedule.</maml:para>
      <maml:para>- "WarnAboutMissingLogic" Property Of Type Boolean. Indicates Whether The PSModule Will Throw Warnings Whenever An AD Managed Group Have Either AddLogic Or RemoveLogic Missing. Whenever You Have Groups Without Automatic Adding Or Removing, Disable This Verification To Avoid Unnecessary Report Events. For Example Whenever You Have Sensitive Groups You May Want To Automate Only The Removal From The Group And Using Formal Approval Process With Manual Adding. This Will Allow No Room For Forgotten Group Members When They Change Their Position Or Leave The Company.</maml:para>
      <maml:para>- "MonthsToKeepProcessingEvents" Property Of Type Int32. Contains The Time Interval In Months To Keep The Processing Events Into The Statistics DataBase. As Processing Events Are Considered Events Related With The Processing Of The Groups Which Lead To Neither Group Members Modification Nor Groups Configuration Modification.</maml:para>
      <maml:para>- "MonthsToKeepProvisioningEvents" Property Of Type Int32. Contains The Time Interval In Months To Keep The Provisioning Events Into The Statistics DataBase. As Provisioning Events Are Considered Events Related With Group Members Modification Or Group Configuration Modification.</maml:para>
    </maml:description>
    <command:syntax>
      <!-- Parameter set: __AllParameterSets -->
      <command:syntaxItem>
        <maml:name>Get-SnsAdGroupMembersPsModuleSettings</maml:name>
        <!-- Parameter: DomainController -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>DomainController</maml:name>
          <maml:description>
            <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
            <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
            <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
            <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
            <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
        <!-- Parameter: Force -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>Force</maml:name>
          <maml:description>
            <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
    <command:parameters>
      <!-- Parameter: DomainController -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>DomainController</maml:name>
        <maml:description>
          <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
          <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
          <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
          <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
          <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: Force -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>Force</maml:name>
        <maml:description>
          <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
        </maml:description>
        <command:parameterValue required="true">SwitchParameter</command:parameterValue>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
    </command:parameters>
    <command:inputTypes />
    <command:returnValues>
      <!-- OutputType: SnsPsModuleSetting -->
      <command:returnValue>
        <dev:type>
          <maml:name>SnsAdGroupMembers.SnsPsModuleSetting</maml:name>
          <maml:uri />
        </dev:type>
      </command:returnValue>
    </command:returnValues>
    <maml:alertSet>
      <maml:title></maml:title>
      <maml:alert>
        <maml:para>AUTHOR: Svetoslav Nedyalkov Savov</maml:para>
        <maml:para>THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK</maml:para>
        <maml:para>OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.</maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
      </maml:alert>
    </maml:alertSet>
    <command:examples>
      <command:example>
        <maml:title>---------- EXAMPLE 1 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsPsModuleSetting]$objSettings = Get-SnsAdGroupMembersPsModuleSettings -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Enumerates The PSModule Configuration.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
    </command:examples>
    <maml:relatedLinks>
      <maml:navigationLink>
        <maml:linkText> svesavov / SnsPsAdGroupMembers - </maml:linkText>
        <maml:uri>https://github.com/svesavov/SnsPsAdGroupMembers</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> PowerShell Gallery - </maml:linkText>
        <maml:uri>https://www.powershellgallery.com/packages/SnsPsAdGroupMembers/</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> Svetoslav Savov on LinkedIn - </maml:linkText>
        <maml:uri>https://www.linkedin.com/in/svetoslavsavov</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> SQLite V3 - </maml:linkText>
        <maml:uri>https://sqlite.org/index.html</maml:uri>
      </maml:navigationLink>
    </maml:relatedLinks>
  </command:command>
  <!-- Cmdlet: Set-SnsAdGroupMembersPsModuleSettings -->
  <command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
    <command:details>
      <command:name>Set-SnsAdGroupMembersPsModuleSettings</command:name>
      <command:verb>Set</command:verb>
      <command:noun>SnsAdGroupMembersPsModuleSettings</command:noun>
      <maml:description>
        <maml:para>Modifies "SnsPsAdGroupMembers" PSModule Configuration.</maml:para>
      </maml:description>
    </command:details>
    <maml:description>
      <maml:para>Modifies "SnsPsAdGroupMembers" PSModule Configuration.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Operation Of "SnsPsAdGroupMembers" PSModule Install It With "AllUsers" Scope. The Idea Behind This Module Is To Be Used On A Scheduled Task "As Service" For The Actual Group Members Management, And Interactively By IT Administrators To Create And Modify The Managed Groups Configuration. This Requires The PSModule To Be Available To Multiple User Accounts.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Creation Of "SnsPsAdGroupMembers" PSModule DataBases, The First Load Of The PSModule Must Be In Elevated Mode. In The Normal Operation The PSModule Does Not Require Elevated Mode. More Information About That Is Provided Further In This Document.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"Why Should I Use This PSModule Instead Of Dynamic Groups?":</maml:para>
      <maml:para>- Well First And Foremost Reason Is Related With The Fact That This PowerShell Module Does Allow To Have Different Logic For Adding And Removing Members. This Is Not Achievable With Dynamic Groups.</maml:para>
      <maml:para>- The Company IT Department Might Need To Use A Single Group For Granting Access Rights In On Premises AD, AzureAD And Use It As Distribution List At The Same Time. Although This Can Be Achieved With Dynamic Groups You Have To Maintain At Least Two Of Them, One For On Premises AD And One For AzureAD.</maml:para>
      <maml:para>- There Are Cases Related With Certain AzureAD Functionalities And Synchronizations With Third Party Cloud Solutions Which Do Not Support Nested And Dynamic Groups. Managing Of Groups With Large Number Of Members In Corporate Environment Without Using Of Group Nestling Could Be Quite Tricky And Related With Lot Of Users Frustration And Administrative Effort.</maml:para>
      <maml:para>- The "SnsPsAdGroupMembers" PSModule Prepare Reports About Modifying Group Members And Audit Of Changes In The Group Management Settings. Whenever A Group Is Used For Granting Sensitive Access Rights Or Managing The Members Of A Sensitive Distribution List, The Group Owners Might Want To Receive Those Reports, Often Immediately After The Above-Mentioned Actions Are Taken.</maml:para>
      <maml:para>- The PSModule Can Be Used Only For Adding Or Only For Removing Members. Using Of Both Is Not Mandatory. This Does Allow Implementation Of Process For Adding Members In Sensitive Groups, Like "Domain Admins" For Example, Following Formal Approval Process, But Removing Members Immediately When The Person Who Owns The Account Leave The Company, Or Change The Position. In This Case There Will Be Zero Tolerance For Users "Forgotten" With More Than Needed Access Rights.</maml:para>
      <maml:para>This PSModule Have The Same Disadvantages And Requirements As The Dynamic Groups. Since The Management Logic Is Based On AD Attribute Values, It Requires The Used Ones To Be Up To Date And Consistent. Some Sort Of Synchronization From The Company HR System Would Address This. Such A Synchronization Is Nice To Have But Not A Requirement. Using My Other PSModule's Will Be Relatively Easy Creation Of Own Synchronization Related With Any On Premises HR Application. Most Of The Cloud Based Ones, Already Have Out Of The Box Synchronization Tools. Creation Of New One Would Not Be Feasible, But It Depends On The API's The Tool Provides.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Manages The Membership Of Active Directory Groups In A Single Domain Forest Based On Predefined Logic About Adding And Removing Members. For That Purpose, The PowerShell Module Uses SQLite Configuration DataBase To Keep Information About:</maml:para>
      <maml:para>- The Managed Groups.</maml:para>
      <maml:para>- The Logic For Adding Members Into Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- The Logic For Removing Members From Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- Explicit Group Inclusions. Those Are AD Objects Which Shall Be Added As Group Members, Although They Do Not Meet The Adding Criteria.</maml:para>
      <maml:para>- Explicit Group Exclusions. Those Are AD Objects Which Shall Not Be Added As Group Members, Although They Do Meet The Adding Criteria.</maml:para>
      <maml:para>- Notification Contacts Who Shall Receive Reports About The Actions And Audit Events Related With Their Own Groups.</maml:para>
      <maml:para>- The PSModule Configuration.</maml:para>
      <maml:para>- Managed Groups Configuration Changes Tracking.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Uses Another SQLite DataBase To Store All The Events Related With The CmdLets Operation And Events Related With Actions Taken On The Managed Groups.</maml:para>
      <maml:para></maml:para>
      <maml:para>To Increase The Confidence In The Automation Among The Group Owners, "SnsPsAdGroupMembers" PSModule Produces Reports Intended To Be Provided To Those Owners, Whenever The PSModule Adds And / Or Removes Members, Whenever It Detects Changes In The Groups Configuration That Might Affect The Group Members, Such Like Changes In The Add Logic, Remove Logic, Explicit Inclusions, Explicit Exclusions And Notification Contacts.</maml:para>
      <maml:para>In Case Of Changes In The Notification Contacts, Both The Old And New Contacts Are Included In The Report Recipients List. The Reports Are Prepared Only When Actual Changes Are Made Or Detected Whenever The Actual Group Management Occur. For That Purpose, The PSModule Uses An SQLite Statistics DataBase To Store Information About:</maml:para>
      <maml:para>- Events Related With Automatic Adding Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Automatic Removing Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Changes In Managed Groups Configuration That Might Affect The Group Membership, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With The Module Operation And Groups Management Intended To Be Provided To The Company IT's. The Internal Events Not Related With Specific Managed Group Are Not Kept In The Statistics DataBase. Therefore The Statistics DataBase Is Not Suitable Source Of Information About Troubleshooting Of Performance, Module Related Issues, And Script Related Issues. However It Is Perfectly Reliable Source Of Troubleshooting Information Related With Troubleshooting Of Incorrect Logic And Any Managed Groups Misconfiguration.</maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Only Prepares Reports And Reverts Them As "SnsReportCollection" Output Object. The Email Relay Options Differ From One Environment To Another, It Is Not Feasible To Maintain Multiple Settings Related With Email Sending In The Configuration DataBase, While Sending Of An Email From PowerShell Is Simple As Running Of A CmdLet. Depending On The Company, Might Be Used Different Languages, Different Wording, Company Branding, Company Stationaries, Company Colors And Company Visual Stylings In The Emails. From That Perspective The PSModule Reverts Reports In Custom Objects And Collections. The User Have To Convert Them To HTML Text And Send Them As Emails, Within The Automation Scripts Which Use "SnsPsAdGroupMembers" Module. The Simplest Way For Doing That Is Using "ConvertTo-Html" And "Send-MailMessage" Native PowerShell CmdLets. Whenever Managed Group Owners Are Not Interested To Receive Any Notifications The Reports For They Own Groups Can Be Disabled Via Leaving Empty The Notification Contacts Setting Of The Group (Or Remove All Notification Contacts For A Managed Group If There Are Already Specified). This Does Not Disable The Logging Of Events Into The Statistics DataBase.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>For DataBase Engine Is Used SQLite. SQLite Is Free Open Source Serverless DataBase, Which Comes With Its Own Advantages And Disadvantages. As Serverless DataBase There Is No Server To Manage The DataBase Requests And Locks. From That Perspective Using A Single SQLite DataBase Either Over Network Or Mapped Drives Or Simultaneously By Multiple Applications / PSSessions Might Lead To Errors In Accessing The DataBase Or DataBase Corruption.</maml:para>
      <maml:para>From That Perspective All The CmdLets Within This Module Have A Feature That Prevents Running Of Those CmdLets In Multiple PowerShell Sessions. All The CmdLets Have Parameter "Force" Which Allows The Usage Of The CmdLets In Multiple PSSessions, Use It At Your Own Risk. The Parameter Is Ignored And Does Not Work When The PSSession Is "As A Service" (In Automation Script Executed With Scheduled Task For Example).</maml:para>
      <maml:para>Both The Configuration And Statistics DataBases Are Located In "C:\ProgramData\SnsAdGroupMembers" By Default. In Order The Folder And DataBase Files To Be Created Properly, The First Run Of This CmdLet To Be Made In Elevated PowerShell Session. Creation Of The DataBase Folder And Setting The Required NTFS Permissions Requires Local Administrator Access Rights. The DataBase Files Can Be Moved / Migrated Into Different Folders, In That Case The Administrator Who Is Doing That Have To Make Sure That The Folder Exists, All The Users That Will Use This PSModule Will Have "Modify" NTFS Permissions Over The Folder And The DataBase Files, Move The DataBase Files Into The New Folder And Properly Provide The Module With The New Folder Absolute (Full) Path.</maml:para>
      <maml:para>Although Using This PSModule On Domain Controllers Is Possible, It Is Against The Best Practices And It Is Not Recommended. All Automations Shall Be Run On Dedicated Virtual Or Physical Machine. From That Perspective It Is Required "Local Admin" Access Rights.</maml:para>
      <maml:para>It Is Not Recommended The DataBase Files To Be Moved, And If That Happen They Shall Be Not Moved On Network Shares Or Mapped Drives. This Will Not Prevent The PSModule To Do Its Job. It Will Introduce Performance Degradation, Possible Interruption In Case Of Network Issues And Eventually Corruption Of The DataBases.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>Never Move DataBases Outside The Default Location When The PSModule Is Installed With Scope "CurrentUser".</maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>"CfgDbFolder" Setting Specifies The Location Of Both Configuration And Statistics DataBases Simultaneously Unless The Statistics DataBase Have Explicitly Specified Location. With Other Words When Modify Configuration DataBase Location And "StatDbFolder" Setting Is Not Used, Both DataBases Have To Be Moved In The New Location.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Contains CmdLets Intended To Be Run Interactively By The User And CmdLets Intended To Be Run Within Automation Scripts On A Schedule As A Service. The CmdLets Intended To Be Used Within Automation Scripts Comply With Additional Requirements Related With Logging, Reporting And Ability To Being Monitored (Using "SnsPsScriptsMonitoring" PSModule For Example). "Invoke-SnsAdGroupMembersManage" Is A CmdLet Intended To Be Used In An Automation Scripts. By Its Nature, This CmdLet Is An Automation Encapsulated Within A CmdLet. The Logs And Events Happening During The CmdLet Run Are Logged In An SQLite DataBase "GroupMembersProvStat.db" Referred Furter As Statistics DataBase. It Could Be Used For Other Reporting Purposes Like Periodical Comprehensive Reports About The Actions Taken By Automation Scripts (This Requires Additional Scripting To Read The DataBase And Prepare The Reports).</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>When Working With Active Directory It Is Important What Identity Attribute Will Be Chosen For Binding To The AD Objects. Although Naturally AD Uses DistinguishedName For Binding And LDAP Queries, It Is Not The Best Possible Identity. The DistinguishedName Is Unique But It Is Not Constant, It Can Be Changed Over The AD Object Life Cycle. An AD Object Can Be Renamed And / Or Moved Into Different Organizational Unit, Or The Organizational Unit Where The Object Is Located Can Be Renamed And / Or Moved. That Will Modify Object's Distinguished Name. In This Case The Active Directory Will Automatically Reflect Those Changes In The Attributes Of The Object And On All Relational Attributes Of The Remaining Objects Which Point To Our Object. For Example "member" Attribute Of All The Groups Where Our AD Object Is Member Of, Or "manager" Attribute Of All Accounts That Our User Is Manager. However AD Will Not Modify Accordingly The PSModule Configuration Stored In An External For The AD DataBase. This Will Lead To Errors And Failures.</maml:para>
      <maml:para>It Is Best Practice The AD Related Applications To Use For Binding Other Identity Attributes Which Do Not Change During The Objects Life Cycle. Those Are "objectGUID" And "objectSid". The Best Practices Gives Preference To The "objectSid" By Various Reasons. Since It Is Possible Groups To Have Member Objects Without "objectSid" (Contact Objects For Example) The "SnsPsAdGroupMembers" PSModule Uses As Identity The "ObjectGUID" Attribute. Thus Way When An Object Is Renamed Or Moved The PSModule Is Not Affected And Continue To Work As Intended.</maml:para>
      <maml:para>The The Well-Known AD Behavior, That When An Object Is Deleted And Then Recreated, All The Access Rights And Group Membership Are Lost, Is Related With The Fact That The Recreated Object Have Different "objectSid". Using The "objectGUID" As Identity Introduces Similar Behavior Of "SnsPsAdGroupMembers". Deletion And Recreation Of An AD Group Object Does Not Automatically Enable It For Automatic Members Management With The Logic Of The Deleted Group.</maml:para>
      <maml:para>The Using "objectGUID" As Identity In The PSModule Configuration Ensures That The PSModule Is Not Affected By Objects Rename Or Objects Move. When A Managed Group, Explicit Inclusion, Explicit Exclusion Is Renamed Or Moved Into Different OU, Their "objectGUID" Remains Intact. And The PSModule Continue To Bind To Those Objects Without Errors. However This Does Introduce Additional Overhead For The CmdLets Intended To Manage The Groups Configuration. When An Object Is Provided To Them They Need To Search For That Object In Active Directory, Enumerate The "objectGUID" Of The Object And Specify The Enumerated Value Into The Configuration DataBase. Since The CmdLets Query AD, That Query Can Be Made Against Multiple Attributes, Which Does Provide Freedom For The User To Use Multitude Of Values When An AD Object Is Provided To A Parameter. Please Refer To Each To The Parameters Sections Of Each CmdLet Help Document.</maml:para>
      <maml:para>When LDAP Queries Are Needed The Things Get More Complicated. The LDAP Queries Work Only With DistinguishedName. When You Need To Query About Reports Of A Person, Or Members Of A Group The AD Expects LDAP Query With DistinguishedName Values. An Example Of Often Use LDAP Query Clause Is:</maml:para>
      <maml:para>"(manager=CN=Jane Smith,CN=Users,DC=contoso,DC=com)"</maml:para>
      <maml:para>If "SnsPsAdGroupMembers" PSModule Keep It As Is Into The Configuration, In Case Of DistinguishedName Change, The Logic Will Revert No Results, Which Might Lead To Removal Of All The Members From The Group. Instead The LDAP Clause Is Stored Like:</maml:para>
      <maml:para>"(manager=00000000-0000-0000-0000-000000000000)"</maml:para>
      <maml:para>This Complicates The PSModule Further, As On The AD Managed Group Configuration Creation / Modification It Have To Evaluate The Specified Parameters, Match Them Using RegEx Pattern About Any Distinguished Names, Bind To The AD Object Using The Matched DistinguishedName, Enumerates The AD Object "objectGUID" And Amend The Matched DistinguishedName With The Enumerated "objectGUID". And Before The Actual AD Managed Group Members Management, It Have To Evaluate The Configuration About "objectGUID" Values Using RegEx Matching, Bind To The AD Object Using The Matched "objectGUID", Enumerate The AD Object DistinguishedName And Amend The "objectGUID" With The Enumerated DistinguishedName. Thus Way Introducing Overhead For The PSModule And For The Domain Controller Which Serves The LDAP Requests.</maml:para>
      <maml:para>To Reduce The Number Of The AD Requests And The Overhead, The PSModule Caches The Attributes Of The Previously Bind To Or Queried About AD Objects, And Consequently Uses The Cache Instead Of Making New AD Requests. The Effectiveness Of The AD Cache Depends On The Similarities In The Configuration Of The Groups.</maml:para>
      <maml:para>The Attributes Modified By The "SnsPsAdGroupMembers" PSModule Like "memberOf" AD Attribute, Are Never Cached. Caching Those Might Lead To False Positive Or Real Errors.</maml:para>
      <maml:para>The Values Of The AD Attributes Without Requirements For Uniqueness Cannot Be Used For Indexing And Searches In The Cache. For Example There Is No Uniqueness Requirement For "cn" Attribute, You Can Have Multiple Objects With The Same "cn" As Long As They Are Located In Different OU's. When A CmdLet Parameter From The PSModule Is Provided With "cn" Value, It Must Make LDAP Search To Enumerate The AD Object, Either To Confirm That The Value Corresponds To An AD Object Or To Throw Error About Multiple Objects. In Case We Have The Specified Value In The Cache It Is Not Certain That There Are No Other Objects With The Same Value In The AD Domain. Whenever We Use AD Attributes With Uniqueness Requirements Like Distinguished Name, For Example Presence Of The Provided Value In The Cache Can Be Safely Assumed As Correct And Unique, In That Case Query Against The AD Domain Is Not Needed. Usage Of Values In Attributes Without Uniqueness Requirements Reduces The Effectiveness Of The AD Cache Feature Further.</maml:para>
      <maml:para>Introducing A Cache In The PSModule Introduces All Generic Disadvantages Related With Caching, Like Cached Outdated Values. The "SnsPsAdGroupMembers" PSModule Keeps The AD Cache In The System Memory. This Does Ensure Maximum Speed For Accessing The Cache, With Negative Impact On The Machine Performance Because Of The Increased Memory Usage. Together With The Feature Which Does Not Allow Usage Of The PSModule In Multiple PSSession (Which Actually Force The Users To Close Their PSSessions Once They Finish Their Job), Ensures Relatively Short Life Span Of The Cached Entries, Thus Way Reducing The Cache Effectiveness But Increasing The Reliability Via Minimizing The Possibility For Issues Related With Outdated Entries.</maml:para>
      <maml:para>Although The Shorter Lifespan Of The Cached Entries Reduces The Possibility For Mistakes, It Does Not Eliminate Them Completely. Mistakes Might Happen Without Corrupted Or Outdated Cached Entry. Let Us Assume We Have A Department Related Group Where Members Are Added Based On Specific Value In The Department AD Attribute And Removed When The Value Is Different. At The Same Time, The Department AD Attribute Is Automatically Synchronized From The Company HR System. In Case Of Department Rebranding The Sync From The HR System Will Modify The Attribute Value Of All Department Members. In That Case All The Department Members Will Be Removed From The Group. This Is Addressed With Introducing Of New Feature Which Prevents Any Members Removal Whenever The Members Enumerated For Removing Are More Than Certain Threshold. The Threshold Is Configurable. The Default Value Is 50%.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" Provides A Feature Intended For Quick Identifying Whether A Group Is Automatically Managed Or Not, Which Is Disabled By Default. It Could Be Very Annoying And Frustrating To Manually Add Or Remove A Member Into A Group And The Automation To Revert The Changes Back Because The Member Does Not Match The Adding Or Match The Removing Criteria For The Automatic Group Members Management. Normally The IT Administrators Would Need To Check In The PS Module Configuration To Verify Whether An AD Group Is Automatically Managed Using The PSModule Before Membership Modification. This Might Lead To Failed Scheduled Tasks Due To Multiple PSSessions With The PSModule Loaded. From That Perspective "SnsPsAdGroupMembers" Stores A Predefined Constant Value In A Predefined AD Attribute Of The AD Managed Groups And Clears The Predefined Constant Value From The Predefined AD Attribute Of The Not Managed Groups. Therefore The Company IT Administrators Just Need To Look At That Attribute Before Manually Add Or Remove Groups Members In An AD Group.</maml:para>
      <maml:para>To Enable This Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet, To Specify An AD Attribute And A Constant Value Which Shall Be Set On The AD Managed Groups. To Disable That Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet To Clear Either The Value Or The AD Attribute Used By This Feature Or Both. When Enabled On A Scheduled Job After Actual Group Management "Invoke-SnsAdGroupMembersManage" Sets The Predefined Constant Value Into The Predefined AD Attribute Of All Enabled AD Managed Groups And Clears The Value From All Not Managed AD Groups. Therefore Once The Feature Is Disabled The User Have To Manually Clear The Value From The AD Attribute Of All The Groups In Case The Feature Was Ever Used. Changing The Attribute Will Not Clear The Value From The Old Attribute.</maml:para>
      <maml:para>NOTE: This Feature Considers As Managed Only The Groups That Are Enabled In The Groups Configuration. Disabling A Group From Automatic Members Management, Even Temporary Will Clear The AD Attribute Used By This Feature, Indicating To The Corporate IT Administrators, That The Group Membership Can Be Managed Manually.</maml:para>
      <maml:para>NOTE: This Feature Can Use Only AD Attributes With Type Of Single Valued String.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>Set-SnsAdGroupMembersPsModuleSettings Is Intended To Be Used Interactively By A User To Modify The PSModule Configuration Into The Configuration DataBase.</maml:para>
      <maml:para>NOTE: Please Make Sure That The PowerShell Is Closed, When You Finish With The Work On The Managed AD Groups Configuration. Otherwise Either The Other Users Or Any Automated Task Will Be Prevented From Work With The PSModule.</maml:para>
      <maml:para>NOTE: "Set-SnsAdGroupMembersPsModuleSettings" CmdLet Modifies "SnsPsAdGroupMembers" PSModule Configuration Settings Kept In The Configuration DataBase. The CmdLet Requires The Configuration DataBase To Exists And To Contain The Default Settings. The CmdLet Cannot Be Used To Modify The DataBase Paths. If You Need To Do So Please Check The Comments In "SnsPsAdGroupMembers.psm1" File. The Location Of That File Will Depend From The Instalation Scope When You Installed The PSModule. If You Followed The Warnings Above It Would Be:</maml:para>
      <maml:para>"C:\Program Files\WindowsPowerShell\Modules\SnsPsAdGroupMembers\&lt;X&gt;.&lt;X&gt;.&lt;X&gt;.&lt;X&gt;\SnsPsAdGroupMembers.psm1"</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In Parameters Validation "Get-SnsAdManagedGroup" CmdLet Verifies Whether The Supplied By The User Values Are Valid, Within The Predefined Ranges And From Required Type. The Validation Of "AutomationManagedAttribute" And "VerifyLeaversOu" Parameters Actually Make Queries Against AD And Verifies The Attribute And The Organizational Units Existence.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "BeginProcessing" Method "Get-SnsAdManagedGroup" CmdLet Initializes The PSModule Configuration. Verifies The Existence, The Schema And The Integrity Of The Configuration DataBase. Verifies About Other PowerShell Processes Using "SnsPsAdGroupMembers" PSModule. This CmdLet Does Not Have "Force" Parameter. It Does Not Makes Any Sense To Modify The PSModule Configuration While Another Process Is Running And Possibly Manages The Groups Membership.</maml:para>
      <maml:para>Next The CmdLet Evaluates The Arguments Supplied To The Parameters And Compare Them With The Current PSModule Configuration. Those That Are Different Are Modified. If No Differences To Be Set In The Configuration DataBase The CmdLet Reverts Warning That No Configuration Changes Are Made.</maml:para>
      <maml:para>Then Sends Out The PSModule Configuration Object.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The CmdLet Reverts SnsPsModuleSetting Object With The Following Properties:</maml:para>
      <maml:para>- "AutomationManagedAttribute" Property Of Type String. Represents The AD Attribute Name As It Is Seen In Attributes Tab Of "Active Directory Users and Computers" Management Console, Used To Indicate Whether Or Not An AD Group Is Automatically Managed. Whenever The Property Have No Value The Feature Is Disabled.</maml:para>
      <maml:para>- "AutomationManagedValue" Property Of Type String. Represents The Value Which The PSModule Put In "AutomationManagedAttribute" To Indicate Whether Or Not An AD Group Is Automatically Managed. Whenever The Property Have No Value The Feature Is Disabled.</maml:para>
      <maml:para>- "BlockRemovalPercent" Property Of Type Int32. Contains The Threshold In Percent About Block Automated Group Members Removal. In Case Of Organization Changes Or Other Reason, After The AD Accounts Synchronization From An HR System, It Might Happen That All The Members Of An Automated Group Match The Removal Logic. To Prevent The Removal Of All The Members From A Group "SnsPsAdGroupMembers" PSModule Evaluate The Number Of The Current Members, The Members Evaluated For Removal And Calculates Removal Percentage. In case The Removal Percentage Is Bigger Than The Value Specified In This Parameter, No Members Are Removed And The Issue Is Reported.</maml:para>
      <maml:para>- "VerifyLeaversAccountDisabled" Property Of Type Boolean. Indicates Whether The AD Managed Group Configuration Is Verified About Bindings To Disabled AD Accounts. Disabling This Verification Will Stop The Events Generation When Either Group Notification Contact Or Exclusion Or Inclusion User Leave The Company And His / Hers AD Account Get Disabled On All AD Managed Groups. In That Case An IT Administrator Should Regularly Check The AD Managed Groups Configuration. To Prevent False Positive Report Events, This Verification Have To Be Disabled Whenever Either Notification Contacts Or Inclusions Or Exclusions Or AddLogic Or RemoveLogic Contains Shared Mailboxes.</maml:para>
      <maml:para>- "VerifyLeaversOu" Property Of Type String Array. Contains An Array With DistinguishedName Parts Of The Organizational Units Where The Leavers Accounts Are Kept. According To The Best Practices, When A User Leave The Company, The AD Account Is Kept Disabled For Certain Period Of Time. Whenever The Process Include Moving The Leavers Accounts To A Dedicated OU This Features Comes In Handy. The PSModule Verifies The Groups Configuration About Bindings To AD Accounts Located In Those OU's, And Report That. This Is Very Useful Whenever "VerifyLeaversAccountDisabled" Feature Is Disabled. To Disable This Feature Assign Empty Array.</maml:para>
      <maml:para>- "ReportPositionIssuesWithPrerequisiteGroups" Property Of Type Boolean. Indicates Whether The AD Managed Group Configuration Is Verified About AD Managed Groups Used As Input In Other AD Managed Groups Logic, And Whether The Prerequisite Group Is Managed After The Dependent One. When The Prerequisite Group Is Managed Beforehand, On The Dependent Group Management Will Have Up To Date Input. Otherwise The Dependent Group Will Be Updated Accordingly Earliest On The Next Management Schedule.</maml:para>
      <maml:para>- "WarnAboutMissingLogic" Property Of Type Boolean. Indicates Whether The PSModule Will Throw Warnings Whenever An AD Managed Group Have Either AddLogic Or RemoveLogic Missing. Whenever You Have Groups Without Automatic Adding Or Removing, Disable This Verification To Avoid Unnecessary Report Events. For Example Whenever You Have Sensitive Groups You May Want To Automate Only The Removal From The Group And Using Formal Approval Process With Manual Adding. This Will Allow No Room For Forgotten Group Members When They Change Their Position Or Leave The Company.</maml:para>
      <maml:para>- "MonthsToKeepProcessingEvents" Property Of Type Int32. Contains The Time Interval In Months To Keep The Processing Events Into The Statistics DataBase. As Processing Events Are Considered Events Related With The Processing Of The Groups Which Lead To Neither Group Members Modification Nor Groups Configuration Modification.</maml:para>
      <maml:para>- "MonthsToKeepProvisioningEvents" Property Of Type Int32. Contains The Time Interval In Months To Keep The Provisioning Events Into The Statistics DataBase. As Provisioning Events Are Considered Events Related With Group Members Modification Or Group Configuration Modification.</maml:para>
    </maml:description>
    <command:syntax>
      <!-- Parameter set: __AllParameterSets -->
      <command:syntaxItem>
        <maml:name>Set-SnsAdGroupMembersPsModuleSettings</maml:name>
        <!-- Parameter: AutomationManagedAttribute -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>AutomationManagedAttribute</maml:name>
          <maml:description>
            <maml:para>Specifies An AD Attribute Where Will Be Indicated Whether An AD Group Is Automatically Managed Or Not.</maml:para>
            <maml:para>The Attribute Syntax Must Be Exactly As It Is Shown In Attributes Tab Of "Active Directory Users and Computers" Console.</maml:para>
            <maml:para>To Clear Existing AutomationManagedAttribute Use Either $null Or "".</maml:para>
            <maml:para>Clearing AutomationManagedAttribute Disables The Feature About Indicating Automatically Managed AD Groups.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
        <!-- Parameter: AutomationManagedValue -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>AutomationManagedValue</maml:name>
          <maml:description>
            <maml:para>Specifies A Value To Indicat Whether An AD Group Is Automatically Managed Or Not.</maml:para>
            <maml:para>The Specified Value Will Be Set In The AutomationManagedAttribute Of The Automatically Managed Groups. If Not Managed Or Disabled Group Contains The Specified AutomationManagedValue In The Specified AutomationManagedAttribute, It Will Be Cleared.</maml:para>
            <maml:para>To Clear Existing AutomationManagedValue Use Either $null Or "".</maml:para>
            <maml:para>Clearing AutomationManagedValue Disables The Feature About Indicating Automatically Managed AD Groups.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
        <!-- Parameter: BlockRemovalPercent -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>BlockRemovalPercent</maml:name>
          <maml:description>
            <maml:para>Specifies A Threshold In Precents To Block Automatic Members Removal.</maml:para>
            <maml:para>To Allow Removal Of All Members Without Block, Set The Threshold To 100%.</maml:para>
            <maml:para>When The Threshold Is 0% All Removals Will Be Blocked And This Will Be Reported.</maml:para>
          </maml:description>
          <command:parameterValue required="true">int</command:parameterValue>
          <dev:type>
            <maml:name>System.Int32</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>0</dev:defaultValue>
        </command:parameter>
        <!-- Parameter: DomainController -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>DomainController</maml:name>
          <maml:description>
            <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
            <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
            <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
            <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
            <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
        <!-- Parameter: MonthsToKeepProcessingEvents -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>MonthsToKeepProcessingEvents</maml:name>
          <maml:description>
            <maml:para>Specifies A Threshold In Months To Preserve The Processing Events In The Statistics Database.</maml:para>
            <maml:para>As Processing Events Are Considered Events Related With The Processing Of The Groups Which Lead To Neither Group Members Modification Nor Groups Configuration Modification.</maml:para>
            <maml:para>Statistics DataBase Would Grow With The Time. In Case The Events Are Not Deleted The Growth Would Be Endless, Which Will Lead To Performance Issues. Depending On The Environment Size And The Number Of The Automated AD Groups The DataBase Might Have Significant Tendency To Grow. From That Perspective The Outdated Events Deletion Cannot Be Disabled.</maml:para>
            <maml:para>Deletion Of Entries Within DataBase Tables Creates White Space Within The DataBase Files. The White Space Can Be Used For New Entries In The Tables, Which Leads Over The Time To DataBase File Fragmentation, Which Leads To Performance Issues As Well. To Avoid That The DataBase File Must Be Maintained On Regular Basis Using "Invoke-SnsStatisticsDataBaseDefragmentation".</maml:para>
          </maml:description>
          <command:parameterValue required="true">int</command:parameterValue>
          <dev:type>
            <maml:name>System.Int32</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>1</dev:defaultValue>
        </command:parameter>
        <!-- Parameter: MonthsToKeepProvisioningEvents -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>MonthsToKeepProvisioningEvents</maml:name>
          <maml:description>
            <maml:para>Specifies A Threshold In Months To Preserve The Processing Events In The Statistics Database.</maml:para>
            <maml:para>As Provisioning Events Are Considered Events Related With Group Members Modification Or Group Configuration Modification. With Other Words The Ones Send To The Group Notification Contacts.</maml:para>
            <maml:para>Statistics DataBase Would Grow With The Time. In Case The Events Are Not Deleted The Growth Would Be Endless, Which Will Lead To Performance Issues. Depending On The Environment Size And The Number Of The Automated AD Groups The DataBase Might Have Significant Tendency To Grow. From That Perspective The Outdated Events Deletion Cannot Be Disabled.</maml:para>
            <maml:para>Deletion Of Entries Within DataBase Tables Creates White Space Within The DataBase Files. The White Space Can Be Used For New Entries In The Tables, Which Leads Over The Time To DataBase File Fragmentation, Which Leads To Performance Issues As Well. To Avoid That The DataBase File Must Be Maintained On Regular Basis Using "Invoke-SnsStatisticsDataBaseDefragmentation".</maml:para>
          </maml:description>
          <command:parameterValue required="true">int</command:parameterValue>
          <dev:type>
            <maml:name>System.Int32</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>1</dev:defaultValue>
        </command:parameter>
        <!-- Parameter: ReportPositionIssuesWithPrerequisiteGroups -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>ReportPositionIssuesWithPrerequisiteGroups</maml:name>
          <maml:description>
            <maml:para>Enables And Disables The Evaluation Of The AD Managed Groups Configuration About Dependencies Between The Groups And Whether The Processing Order OF The Prerequisite And Dependent Groups Is Correct.</maml:para>
          </maml:description>
          <command:parameterValue required="true">bool</command:parameterValue>
          <dev:type>
            <maml:name>System.Boolean</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
        <!-- Parameter: VerifyLeaversAccountDisabled -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>VerifyLeaversAccountDisabled</maml:name>
          <maml:description>
            <maml:para>Enables And Disables The Evaluation Of The AD Managed Groups Configuration About Bindings To Disabled AD Accounts.</maml:para>
            <maml:para>When Enabled The AddLogic, RemoveLogic, Notification Contacts, Explicit Inclusions And Explicit Exclusions Of The AD Managed Groups Will Be Verified About Values Which Corresponds To Disabled AD Accounts. If The Evaluation Reverts Any Results The Issue Will Be Included In The Reports. Whenever A Notification Contact Is Disabled AD Account It Will Be Amended With The Email Of The Manager Of The User Taken From "manager" Attribute Of The Disabled Account.</maml:para>
            <maml:para>Disable This Feature When You Use Bindings To Shared Mailboxes, To Prevent False Positives.</maml:para>
          </maml:description>
          <command:parameterValue required="true">bool</command:parameterValue>
          <dev:type>
            <maml:name>System.Boolean</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
        <!-- Parameter: VerifyLeaversOu -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>VerifyLeaversOu</maml:name>
          <maml:description>
            <maml:para>Specifies An Array With Part Of Distinguished Names Which Uniquely Identify The AD Organizational Units Intended To Keep The Leavers AD Accounts.</maml:para>
            <maml:para>EXAMPLE: ",OU=Leavers,", ",OU=Disabled Users,DC=contoso,DC=com"</maml:para>
            <maml:para>Whenever The Leavers Process Requires The AD Accounts Of The Users Who Left The Company To Be Moved Into Dedicated OU's, The PSModule Verifies About Values That Corresponds To Leavers Accounts Located In Those OU's In The AD Managed Group Configuration.</maml:para>
            <maml:para>Whenever Shared Mailboxes Are Used In The AD Managed Groups Configuration And VerifyLeaversAccountDisabled Is Disabled, Only This Feature Remains To Report When An AD Managed Group Configuration Is Outdated.</maml:para>
            <maml:para>Whenever Your Company Leavers Process Does Not Require The Leavers AD Accounts To Be Moved Into Dedicated OU's, This Feature Must Be Disabled.</maml:para>
            <maml:para>To Disable This Feature Set $null Or @().</maml:para>
          </maml:description>
          <command:parameterValue required="true">string[]</command:parameterValue>
          <dev:type>
            <maml:name>System.String[]</maml:name>
            <maml:uri />
          </dev:type>
        </command:parameter>
        <!-- Parameter: WarnAboutMissingLogic -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>WarnAboutMissingLogic</maml:name>
          <maml:description>
            <maml:para>Enables And Disables The Evaluation Of The AD Managed Groups Configuration About Groups With Missing Either AddLogic Or Remove Logic.</maml:para>
            <maml:para>Whenever You Intentionally Need To Do So, This Verification Have To Be Disabled.</maml:para>
          </maml:description>
          <command:parameterValue required="true">bool</command:parameterValue>
          <dev:type>
            <maml:name>System.Boolean</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
    <command:parameters>
      <!-- Parameter: AutomationManagedAttribute -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>AutomationManagedAttribute</maml:name>
        <maml:description>
          <maml:para>Specifies An AD Attribute Where Will Be Indicated Whether An AD Group Is Automatically Managed Or Not.</maml:para>
          <maml:para>The Attribute Syntax Must Be Exactly As It Is Shown In Attributes Tab Of "Active Directory Users and Computers" Console.</maml:para>
          <maml:para>To Clear Existing AutomationManagedAttribute Use Either $null Or "".</maml:para>
          <maml:para>Clearing AutomationManagedAttribute Disables The Feature About Indicating Automatically Managed AD Groups.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: AutomationManagedValue -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>AutomationManagedValue</maml:name>
        <maml:description>
          <maml:para>Specifies A Value To Indicat Whether An AD Group Is Automatically Managed Or Not.</maml:para>
          <maml:para>The Specified Value Will Be Set In The AutomationManagedAttribute Of The Automatically Managed Groups. If Not Managed Or Disabled Group Contains The Specified AutomationManagedValue In The Specified AutomationManagedAttribute, It Will Be Cleared.</maml:para>
          <maml:para>To Clear Existing AutomationManagedValue Use Either $null Or "".</maml:para>
          <maml:para>Clearing AutomationManagedValue Disables The Feature About Indicating Automatically Managed AD Groups.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: BlockRemovalPercent -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>BlockRemovalPercent</maml:name>
        <maml:description>
          <maml:para>Specifies A Threshold In Precents To Block Automatic Members Removal.</maml:para>
          <maml:para>To Allow Removal Of All Members Without Block, Set The Threshold To 100%.</maml:para>
          <maml:para>When The Threshold Is 0% All Removals Will Be Blocked And This Will Be Reported.</maml:para>
        </maml:description>
        <command:parameterValue required="true">int</command:parameterValue>
        <dev:type>
          <maml:name>System.Int32</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>0</dev:defaultValue>
      </command:parameter>
      <!-- Parameter: VerifyLeaversAccountDisabled -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>VerifyLeaversAccountDisabled</maml:name>
        <maml:description>
          <maml:para>Enables And Disables The Evaluation Of The AD Managed Groups Configuration About Bindings To Disabled AD Accounts.</maml:para>
          <maml:para>When Enabled The AddLogic, RemoveLogic, Notification Contacts, Explicit Inclusions And Explicit Exclusions Of The AD Managed Groups Will Be Verified About Values Which Corresponds To Disabled AD Accounts. If The Evaluation Reverts Any Results The Issue Will Be Included In The Reports. Whenever A Notification Contact Is Disabled AD Account It Will Be Amended With The Email Of The Manager Of The User Taken From "manager" Attribute Of The Disabled Account.</maml:para>
          <maml:para>Disable This Feature When You Use Bindings To Shared Mailboxes, To Prevent False Positives.</maml:para>
        </maml:description>
        <command:parameterValue required="true">bool</command:parameterValue>
        <dev:type>
          <maml:name>System.Boolean</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
      <!-- Parameter: VerifyLeaversOu -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>VerifyLeaversOu</maml:name>
        <maml:description>
          <maml:para>Specifies An Array With Part Of Distinguished Names Which Uniquely Identify The AD Organizational Units Intended To Keep The Leavers AD Accounts.</maml:para>
          <maml:para>EXAMPLE: ",OU=Leavers,", ",OU=Disabled Users,DC=contoso,DC=com"</maml:para>
          <maml:para>Whenever The Leavers Process Requires The AD Accounts Of The Users Who Left The Company To Be Moved Into Dedicated OU's, The PSModule Verifies About Values That Corresponds To Leavers Accounts Located In Those OU's In The AD Managed Group Configuration.</maml:para>
          <maml:para>Whenever Shared Mailboxes Are Used In The AD Managed Groups Configuration And VerifyLeaversAccountDisabled Is Disabled, Only This Feature Remains To Report When An AD Managed Group Configuration Is Outdated.</maml:para>
          <maml:para>Whenever Your Company Leavers Process Does Not Require The Leavers AD Accounts To Be Moved Into Dedicated OU's, This Feature Must Be Disabled.</maml:para>
          <maml:para>To Disable This Feature Set $null Or @().</maml:para>
        </maml:description>
        <command:parameterValue required="true">string[]</command:parameterValue>
        <dev:type>
          <maml:name>System.String[]</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <!-- Parameter: ReportPositionIssuesWithPrerequisiteGroups -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>ReportPositionIssuesWithPrerequisiteGroups</maml:name>
        <maml:description>
          <maml:para>Enables And Disables The Evaluation Of The AD Managed Groups Configuration About Dependencies Between The Groups And Whether The Processing Order OF The Prerequisite And Dependent Groups Is Correct.</maml:para>
        </maml:description>
        <command:parameterValue required="true">bool</command:parameterValue>
        <dev:type>
          <maml:name>System.Boolean</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
      <!-- Parameter: WarnAboutMissingLogic -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>WarnAboutMissingLogic</maml:name>
        <maml:description>
          <maml:para>Enables And Disables The Evaluation Of The AD Managed Groups Configuration About Groups With Missing Either AddLogic Or Remove Logic.</maml:para>
          <maml:para>Whenever You Intentionally Need To Do So, This Verification Have To Be Disabled.</maml:para>
        </maml:description>
        <command:parameterValue required="true">bool</command:parameterValue>
        <dev:type>
          <maml:name>System.Boolean</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
      <!-- Parameter: MonthsToKeepProcessingEvents -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>MonthsToKeepProcessingEvents</maml:name>
        <maml:description>
          <maml:para>Specifies A Threshold In Months To Preserve The Processing Events In The Statistics Database.</maml:para>
          <maml:para>As Processing Events Are Considered Events Related With The Processing Of The Groups Which Lead To Neither Group Members Modification Nor Groups Configuration Modification.</maml:para>
          <maml:para>Statistics DataBase Would Grow With The Time. In Case The Events Are Not Deleted The Growth Would Be Endless, Which Will Lead To Performance Issues. Depending On The Environment Size And The Number Of The Automated AD Groups The DataBase Might Have Significant Tendency To Grow. From That Perspective The Outdated Events Deletion Cannot Be Disabled.</maml:para>
          <maml:para>Deletion Of Entries Within DataBase Tables Creates White Space Within The DataBase Files. The White Space Can Be Used For New Entries In The Tables, Which Leads Over The Time To DataBase File Fragmentation, Which Leads To Performance Issues As Well. To Avoid That The DataBase File Must Be Maintained On Regular Basis Using "Invoke-SnsStatisticsDataBaseDefragmentation".</maml:para>
        </maml:description>
        <command:parameterValue required="true">int</command:parameterValue>
        <dev:type>
          <maml:name>System.Int32</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>1</dev:defaultValue>
      </command:parameter>
      <!-- Parameter: MonthsToKeepProvisioningEvents -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>MonthsToKeepProvisioningEvents</maml:name>
        <maml:description>
          <maml:para>Specifies A Threshold In Months To Preserve The Processing Events In The Statistics Database.</maml:para>
          <maml:para>As Provisioning Events Are Considered Events Related With Group Members Modification Or Group Configuration Modification. With Other Words The Ones Send To The Group Notification Contacts.</maml:para>
          <maml:para>Statistics DataBase Would Grow With The Time. In Case The Events Are Not Deleted The Growth Would Be Endless, Which Will Lead To Performance Issues. Depending On The Environment Size And The Number Of The Automated AD Groups The DataBase Might Have Significant Tendency To Grow. From That Perspective The Outdated Events Deletion Cannot Be Disabled.</maml:para>
          <maml:para>Deletion Of Entries Within DataBase Tables Creates White Space Within The DataBase Files. The White Space Can Be Used For New Entries In The Tables, Which Leads Over The Time To DataBase File Fragmentation, Which Leads To Performance Issues As Well. To Avoid That The DataBase File Must Be Maintained On Regular Basis Using "Invoke-SnsStatisticsDataBaseDefragmentation".</maml:para>
        </maml:description>
        <command:parameterValue required="true">int</command:parameterValue>
        <dev:type>
          <maml:name>System.Int32</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>1</dev:defaultValue>
      </command:parameter>
      <!-- Parameter: DomainController -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>DomainController</maml:name>
        <maml:description>
          <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
          <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
          <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
          <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
          <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
    </command:parameters>
    <command:inputTypes />
    <command:returnValues>
      <!-- OutputType: SnsPsModuleSetting -->
      <command:returnValue>
        <dev:type>
          <maml:name>SnsAdGroupMembers.SnsPsModuleSetting</maml:name>
          <maml:uri />
        </dev:type>
      </command:returnValue>
    </command:returnValues>
    <maml:alertSet>
      <maml:title></maml:title>
      <maml:alert>
        <maml:para>AUTHOR: Svetoslav Nedyalkov Savov</maml:para>
        <maml:para>THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK</maml:para>
        <maml:para>OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.</maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
      </maml:alert>
    </maml:alertSet>
    <command:examples>
      <command:example>
        <maml:title>---------- EXAMPLE 1 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsPsModuleSetting]$objSettings = Set-SnsAdGroupMembersPsModuleSettings `
-AutomationManagedAttribute "extensionAttribute15" -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Configures The PSModule To Indicate In "extensionAttribute15" Whether An AD Group Is Automatically Managed.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 2 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsPsModuleSetting]$objSettings = Set-SnsAdGroupMembersPsModuleSettings `
-AutomationManagedValue "Group Members Automation" -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Configures The PSModule To Indicate With Value "Group Members Automation" Whether An AD Group Is Automatically Managed.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 3 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsPsModuleSetting]$objSettings = Set-SnsAdGroupMembersPsModuleSettings `
-BlockRemovalPercent 50 -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Configures The PSModule To Prevent Members Removal When It Evaluates More Than 50% Of Members To Remove.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 4 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsPsModuleSetting]$objSettings = Set-SnsAdGroupMembersPsModuleSettings `
-VerifyLeaversAccountDisabled:$true -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Configures The PSModule To Verify About Disabled Accounts In The AD Managed Group Configuration.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 5 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsPsModuleSetting]$objSettings = Set-SnsAdGroupMembersPsModuleSettings `
-VerifyLeaversOu ",OU=Leavers,", ",OU=Disabled Users," -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Configures The PSModule To Consider As Leavers All Accounts Present In The AD Managed Groups Configuration Which DistinguishedName Contains At Least One Of The Specified Arguments.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 6 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsPsModuleSetting]$objSettings = Set-SnsAdGroupMembersPsModuleSettings `
-ReportPositionIssuesWithPrerequisiteGroups:$true -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Configures The PSModule To Verify About Dependancies Between The AD Managed Groups.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 7 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsPsModuleSetting]$objSettings = Set-SnsAdGroupMembersPsModuleSettings `
-WarnAboutMissingLogic:$true -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Configures The PSModule To Verify About AD Managed Groups Without AddLogic Or RemoveLogic.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 8 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsPsModuleSetting]$objSettings = Set-SnsAdGroupMembersPsModuleSettings `
-MonthsToKeepProcessingEvents 14 -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Configures The PSModule Keep The Processing Events In The Statistics DataBase For 14 Months.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 9 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsPsModuleSetting]$objSettings = Set-SnsAdGroupMembersPsModuleSettings `
-MonthsToKeepProvisioningEvents 14 -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Configures The PSModule Keep The Provisioning Events In The Statistics DataBase For 14 Months.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 10 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsPsModuleSetting]$objSettings = Set-SnsAdGroupMembersPsModuleSettings `
-VerifyLeaversOu $null -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Clears The Setting And Disables The Verification About AD Accounts Located In Leavers Organizational Units.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
    </command:examples>
    <maml:relatedLinks>
      <maml:navigationLink>
        <maml:linkText> svesavov / SnsPsAdGroupMembers - </maml:linkText>
        <maml:uri>https://github.com/svesavov/SnsPsAdGroupMembers</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> PowerShell Gallery - </maml:linkText>
        <maml:uri>https://www.powershellgallery.com/packages/SnsPsAdGroupMembers/</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> Svetoslav Savov on LinkedIn - </maml:linkText>
        <maml:uri>https://www.linkedin.com/in/svetoslavsavov</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> SQLite V3 - </maml:linkText>
        <maml:uri>https://sqlite.org/index.html</maml:uri>
      </maml:navigationLink>
    </maml:relatedLinks>
  </command:command>
  <!-- Cmdlet: Get-SnsAdManagedGroup -->
  <command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
    <command:details>
      <command:name>Get-SnsAdManagedGroup</command:name>
      <command:verb>Get</command:verb>
      <command:noun>SnsAdManagedGroup</command:noun>
      <maml:description>
        <maml:para>Enumerates Managed Active Directory Group Configuration.</maml:para>
      </maml:description>
    </command:details>
    <maml:description>
      <maml:para>Enumerates Managed Active Directory Group Configuration.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Operation Of "SnsPsAdGroupMembers" PSModule Install It With "AllUsers" Scope. The Idea Behind This Module Is To Be Used On A Scheduled Task "As Service" For The Actual Group Members Management, And Interactively By IT Administrators To Create And Modify The Managed Groups Configuration. This Requires The PSModule To Be Available To Multiple User Accounts.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Creation Of "SnsPsAdGroupMembers" PSModule DataBases, The First Load Of The PSModule Must Be In Elevated Mode. In The Normal Operation The PSModule Does Not Require Elevated Mode. More Information About That Is Provided Further In This Document.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"Why Should I Use This PSModule Instead Of Dynamic Groups?":</maml:para>
      <maml:para>- Well First And Foremost Reason Is Related With The Fact That This PowerShell Module Does Allow To Have Different Logic For Adding And Removing Members. This Is Not Achievable With Dynamic Groups.</maml:para>
      <maml:para>- The Company IT Department Might Need To Use A Single Group For Granting Access Rights In On Premises AD, AzureAD And Use It As Distribution List At The Same Time. Although This Can Be Achieved With Dynamic Groups You Have To Maintain At Least Two Of Them, One For On Premises AD And One For AzureAD.</maml:para>
      <maml:para>- There Are Cases Related With Certain AzureAD Functionalities And Synchronizations With Third Party Cloud Solutions Which Do Not Support Nested And Dynamic Groups. Managing Of Groups With Large Number Of Members In Corporate Environment Without Using Of Group Nestling Could Be Quite Tricky And Related With Lot Of Users Frustration And Administrative Effort.</maml:para>
      <maml:para>- The "SnsPsAdGroupMembers" PSModule Prepare Reports About Modifying Group Members And Audit Of Changes In The Group Management Settings. Whenever A Group Is Used For Granting Sensitive Access Rights Or Managing The Members Of A Sensitive Distribution List, The Group Owners Might Want To Receive Those Reports, Often Immediately After The Above-Mentioned Actions Are Taken.</maml:para>
      <maml:para>- The PSModule Can Be Used Only For Adding Or Only For Removing Members. Using Of Both Is Not Mandatory. This Does Allow Implementation Of Process For Adding Members In Sensitive Groups, Like "Domain Admins" For Example, Following Formal Approval Process, But Removing Members Immediately When The Person Who Owns The Account Leave The Company, Or Change The Position. In This Case There Will Be Zero Tolerance For Users "Forgotten" With More Than Needed Access Rights.</maml:para>
      <maml:para>This PSModule Have The Same Disadvantages And Requirements As The Dynamic Groups. Since The Management Logic Is Based On AD Attribute Values, It Requires The Used Ones To Be Up To Date And Consistent. Some Sort Of Synchronization From The Company HR System Would Address This. Such A Synchronization Is Nice To Have But Not A Requirement. Using My Other PSModule's Will Be Relatively Easy Creation Of Own Synchronization Related With Any On Premises HR Application. Most Of The Cloud Based Ones, Already Have Out Of The Box Synchronization Tools. Creation Of New One Would Not Be Feasible, But It Depends On The API's The Tool Provides.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Manages The Membership Of Active Directory Groups In A Single Domain Forest Based On Predefined Logic About Adding And Removing Members. For That Purpose, The PowerShell Module Uses SQLite Configuration DataBase To Keep Information About:</maml:para>
      <maml:para>- The Managed Groups.</maml:para>
      <maml:para>- The Logic For Adding Members Into Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- The Logic For Removing Members From Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- Explicit Group Inclusions. Those Are AD Objects Which Shall Be Added As Group Members, Although They Do Not Meet The Adding Criteria.</maml:para>
      <maml:para>- Explicit Group Exclusions. Those Are AD Objects Which Shall Not Be Added As Group Members, Although They Do Meet The Adding Criteria.</maml:para>
      <maml:para>- Notification Contacts Who Shall Receive Reports About The Actions And Audit Events Related With Their Own Groups.</maml:para>
      <maml:para>- The PSModule Configuration.</maml:para>
      <maml:para>- Managed Groups Configuration Changes Tracking.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Uses Another SQLite DataBase To Store All The Events Related With The CmdLets Operation And Events Related With Actions Taken On The Managed Groups.</maml:para>
      <maml:para></maml:para>
      <maml:para>To Increase The Confidence In The Automation Among The Group Owners, "SnsPsAdGroupMembers" PSModule Produces Reports Intended To Be Provided To Those Owners, Whenever The PSModule Adds And / Or Removes Members, Whenever It Detects Changes In The Groups Configuration That Might Affect The Group Members, Such Like Changes In The Add Logic, Remove Logic, Explicit Inclusions, Explicit Exclusions And Notification Contacts.</maml:para>
      <maml:para>In Case Of Changes In The Notification Contacts, Both The Old And New Contacts Are Included In The Report Recipients List. The Reports Are Prepared Only When Actual Changes Are Made Or Detected Whenever The Actual Group Management Occur. For That Purpose, The PSModule Uses An SQLite Statistics DataBase To Store Information About:</maml:para>
      <maml:para>- Events Related With Automatic Adding Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Automatic Removing Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Changes In Managed Groups Configuration That Might Affect The Group Membership, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With The Module Operation And Groups Management Intended To Be Provided To The Company IT's. The Internal Events Not Related With Specific Managed Group Are Not Kept In The Statistics DataBase. Therefore The Statistics DataBase Is Not Suitable Source Of Information About Troubleshooting Of Performance, Module Related Issues, And Script Related Issues. However It Is Perfectly Reliable Source Of Troubleshooting Information Related With Troubleshooting Of Incorrect Logic And Any Managed Groups Misconfiguration.</maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Only Prepares Reports And Reverts Them As "SnsReportCollection" Output Object. The Email Relay Options Differ From One Environment To Another, It Is Not Feasible To Maintain Multiple Settings Related With Email Sending In The Configuration DataBase, While Sending Of An Email From PowerShell Is Simple As Running Of A CmdLet. Depending On The Company, Might Be Used Different Languages, Different Wording, Company Branding, Company Stationaries, Company Colors And Company Visual Stylings In The Emails. From That Perspective The PSModule Reverts Reports In Custom Objects And Collections. The User Have To Convert Them To HTML Text And Send Them As Emails, Within The Automation Scripts Which Use "SnsPsAdGroupMembers" Module. The Simplest Way For Doing That Is Using "ConvertTo-Html" And "Send-MailMessage" Native PowerShell CmdLets. Whenever Managed Group Owners Are Not Interested To Receive Any Notifications The Reports For They Own Groups Can Be Disabled Via Leaving Empty The Notification Contacts Setting Of The Group (Or Remove All Notification Contacts For A Managed Group If There Are Already Specified). This Does Not Disable The Logging Of Events Into The Statistics DataBase.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>For DataBase Engine Is Used SQLite. SQLite Is Free Open Source Serverless DataBase, Which Comes With Its Own Advantages And Disadvantages. As Serverless DataBase There Is No Server To Manage The DataBase Requests And Locks. From That Perspective Using A Single SQLite DataBase Either Over Network Or Mapped Drives Or Simultaneously By Multiple Applications / PSSessions Might Lead To Errors In Accessing The DataBase Or DataBase Corruption.</maml:para>
      <maml:para>From That Perspective All The CmdLets Within This Module Have A Feature That Prevents Running Of Those CmdLets In Multiple PowerShell Sessions. All The CmdLets Have Parameter "Force" Which Allows The Usage Of The CmdLets In Multiple PSSessions, Use It At Your Own Risk. The Parameter Is Ignored And Does Not Work When The PSSession Is "As A Service" (In Automation Script Executed With Scheduled Task For Example).</maml:para>
      <maml:para>Both The Configuration And Statistics DataBases Are Located In "C:\ProgramData\SnsAdGroupMembers" By Default. In Order The Folder And DataBase Files To Be Created Properly, The First Run Of This CmdLet To Be Made In Elevated PowerShell Session. Creation Of The DataBase Folder And Setting The Required NTFS Permissions Requires Local Administrator Access Rights. The DataBase Files Can Be Moved / Migrated Into Different Folders, In That Case The Administrator Who Is Doing That Have To Make Sure That The Folder Exists, All The Users That Will Use This PSModule Will Have "Modify" NTFS Permissions Over The Folder And The DataBase Files, Move The DataBase Files Into The New Folder And Properly Provide The Module With The New Folder Absolute (Full) Path.</maml:para>
      <maml:para>Although Using This PSModule On Domain Controllers Is Possible, It Is Against The Best Practices And It Is Not Recommended. All Automations Shall Be Run On Dedicated Virtual Or Physical Machine. From That Perspective It Is Required "Local Admin" Access Rights.</maml:para>
      <maml:para>It Is Not Recommended The DataBase Files To Be Moved, And If That Happen They Shall Be Not Moved On Network Shares Or Mapped Drives. This Will Not Prevent The PSModule To Do Its Job. It Will Introduce Performance Degradation, Possible Interruption In Case Of Network Issues And Eventually Corruption Of The DataBases.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>Never Move DataBases Outside The Default Location When The PSModule Is Installed With Scope "CurrentUser".</maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>"CfgDbFolder" Setting Specifies The Location Of Both Configuration And Statistics DataBases Simultaneously Unless The Statistics DataBase Have Explicitly Specified Location. With Other Words When Modify Configuration DataBase Location And "StatDbFolder" Setting Is Not Used, Both DataBases Have To Be Moved In The New Location.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Contains CmdLets Intended To Be Run Interactively By The User And CmdLets Intended To Be Run Within Automation Scripts On A Schedule As A Service. The CmdLets Intended To Be Used Within Automation Scripts Comply With Additional Requirements Related With Logging, Reporting And Ability To Being Monitored (Using "SnsPsScriptsMonitoring" PSModule For Example). "Invoke-SnsAdGroupMembersManage" Is A CmdLet Intended To Be Used In An Automation Scripts. By Its Nature, This CmdLet Is An Automation Encapsulated Within A CmdLet. The Logs And Events Happening During The CmdLet Run Are Logged In An SQLite DataBase "GroupMembersProvStat.db" Referred Furter As Statistics DataBase. It Could Be Used For Other Reporting Purposes Like Periodical Comprehensive Reports About The Actions Taken By Automation Scripts (This Requires Additional Scripting To Read The DataBase And Prepare The Reports).</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>When Working With Active Directory It Is Important What Identity Attribute Will Be Chosen For Binding To The AD Objects. Although Naturally AD Uses DistinguishedName For Binding And LDAP Queries, It Is Not The Best Possible Identity. The DistinguishedName Is Unique But It Is Not Constant, It Can Be Changed Over The AD Object Life Cycle. An AD Object Can Be Renamed And / Or Moved Into Different Organizational Unit, Or The Organizational Unit Where The Object Is Located Can Be Renamed And / Or Moved. That Will Modify Object's Distinguished Name. In This Case The Active Directory Will Automatically Reflect Those Changes In The Attributes Of The Object And On All Relational Attributes Of The Remaining Objects Which Point To Our Object. For Example "member" Attribute Of All The Groups Where Our AD Object Is Member Of, Or "manager" Attribute Of All Accounts That Our User Is Manager. However AD Will Not Modify Accordingly The PSModule Configuration Stored In An External For The AD DataBase. This Will Lead To Errors And Failures.</maml:para>
      <maml:para>It Is Best Practice The AD Related Applications To Use For Binding Other Identity Attributes Which Do Not Change During The Objects Life Cycle. Those Are "objectGUID" And "objectSid". The Best Practices Gives Preference To The "objectSid" By Various Reasons. Since It Is Possible Groups To Have Member Objects Without "objectSid" (Contact Objects For Example) The "SnsPsAdGroupMembers" PSModule Uses As Identity The "ObjectGUID" Attribute. Thus Way When An Object Is Renamed Or Moved The PSModule Is Not Affected And Continue To Work As Intended.</maml:para>
      <maml:para>The The Well-Known AD Behavior, That When An Object Is Deleted And Then Recreated, All The Access Rights And Group Membership Are Lost, Is Related With The Fact That The Recreated Object Have Different "objectSid". Using The "objectGUID" As Identity Introduces Similar Behavior Of "SnsPsAdGroupMembers". Deletion And Recreation Of An AD Group Object Does Not Automatically Enable It For Automatic Members Management With The Logic Of The Deleted Group.</maml:para>
      <maml:para>The Using "objectGUID" As Identity In The PSModule Configuration Ensures That The PSModule Is Not Affected By Objects Rename Or Objects Move. When A Managed Group, Explicit Inclusion, Explicit Exclusion Is Renamed Or Moved Into Different OU, Their "objectGUID" Remains Intact. And The PSModule Continue To Bind To Those Objects Without Errors. However This Does Introduce Additional Overhead For The CmdLets Intended To Manage The Groups Configuration. When An Object Is Provided To Them They Need To Search For That Object In Active Directory, Enumerate The "objectGUID" Of The Object And Specify The Enumerated Value Into The Configuration DataBase. Since The CmdLets Query AD, That Query Can Be Made Against Multiple Attributes, Which Does Provide Freedom For The User To Use Multitude Of Values When An AD Object Is Provided To A Parameter. Please Refer To Each To The Parameters Sections Of Each CmdLet Help Document.</maml:para>
      <maml:para>When LDAP Queries Are Needed The Things Get More Complicated. The LDAP Queries Work Only With DistinguishedName. When You Need To Query About Reports Of A Person, Or Members Of A Group The AD Expects LDAP Query With DistinguishedName Values. An Example Of Often Use LDAP Query Clause Is:</maml:para>
      <maml:para>"(manager=CN=Jane Smith,CN=Users,DC=contoso,DC=com)"</maml:para>
      <maml:para>If "SnsPsAdGroupMembers" PSModule Keep It As Is Into The Configuration, In Case Of DistinguishedName Change, The Logic Will Revert No Results, Which Might Lead To Removal Of All The Members From The Group. Instead The LDAP Clause Is Stored Like:</maml:para>
      <maml:para>"(manager=00000000-0000-0000-0000-000000000000)"</maml:para>
      <maml:para>This Complicates The PSModule Further, As On The AD Managed Group Configuration Creation / Modification It Have To Evaluate The Specified Parameters, Match Them Using RegEx Pattern About Any Distinguished Names, Bind To The AD Object Using The Matched DistinguishedName, Enumerates The AD Object "objectGUID" And Amend The Matched DistinguishedName With The Enumerated "objectGUID". And Before The Actual AD Managed Group Members Management, It Have To Evaluate The Configuration About "objectGUID" Values Using RegEx Matching, Bind To The AD Object Using The Matched "objectGUID", Enumerate The AD Object DistinguishedName And Amend The "objectGUID" With The Enumerated DistinguishedName. Thus Way Introducing Overhead For The PSModule And For The Domain Controller Which Serves The LDAP Requests.</maml:para>
      <maml:para>To Reduce The Number Of The AD Requests And The Overhead, The PSModule Caches The Attributes Of The Previously Bind To Or Queried About AD Objects, And Consequently Uses The Cache Instead Of Making New AD Requests. The Effectiveness Of The AD Cache Depends On The Similarities In The Configuration Of The Groups.</maml:para>
      <maml:para>The Attributes Modified By The "SnsPsAdGroupMembers" PSModule Like "memberOf" AD Attribute, Are Never Cached. Caching Those Might Lead To False Positive Or Real Errors.</maml:para>
      <maml:para>The Values Of The AD Attributes Without Requirements For Uniqueness Cannot Be Used For Indexing And Searches In The Cache. For Example There Is No Uniqueness Requirement For "cn" Attribute, You Can Have Multiple Objects With The Same "cn" As Long As They Are Located In Different OU's. When A CmdLet Parameter From The PSModule Is Provided With "cn" Value, It Must Make LDAP Search To Enumerate The AD Object, Either To Confirm That The Value Corresponds To An AD Object Or To Throw Error About Multiple Objects. In Case We Have The Specified Value In The Cache It Is Not Certain That There Are No Other Objects With The Same Value In The AD Domain. Whenever We Use AD Attributes With Uniqueness Requirements Like Distinguished Name, For Example Presence Of The Provided Value In The Cache Can Be Safely Assumed As Correct And Unique, In That Case Query Against The AD Domain Is Not Needed. Usage Of Values In Attributes Without Uniqueness Requirements Reduces The Effectiveness Of The AD Cache Feature Further.</maml:para>
      <maml:para>Introducing A Cache In The PSModule Introduces All Generic Disadvantages Related With Caching, Like Cached Outdated Values. The "SnsPsAdGroupMembers" PSModule Keeps The AD Cache In The System Memory. This Does Ensure Maximum Speed For Accessing The Cache, With Negative Impact On The Machine Performance Because Of The Increased Memory Usage. Together With The Feature Which Does Not Allow Usage Of The PSModule In Multiple PSSession (Which Actually Force The Users To Close Their PSSessions Once They Finish Their Job), Ensures Relatively Short Life Span Of The Cached Entries, Thus Way Reducing The Cache Effectiveness But Increasing The Reliability Via Minimizing The Possibility For Issues Related With Outdated Entries.</maml:para>
      <maml:para>Although The Shorter Lifespan Of The Cached Entries Reduces The Possibility For Mistakes, It Does Not Eliminate Them Completely. Mistakes Might Happen Without Corrupted Or Outdated Cached Entry. Let Us Assume We Have A Department Related Group Where Members Are Added Based On Specific Value In The Department AD Attribute And Removed When The Value Is Different. At The Same Time, The Department AD Attribute Is Automatically Synchronized From The Company HR System. In Case Of Department Rebranding The Sync From The HR System Will Modify The Attribute Value Of All Department Members. In That Case All The Department Members Will Be Removed From The Group. This Is Addressed With Introducing Of New Feature Which Prevents Any Members Removal Whenever The Members Enumerated For Removing Are More Than Certain Threshold. The Threshold Is Configurable. The Default Value Is 50%.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" Provides A Feature Intended For Quick Identifying Whether A Group Is Automatically Managed Or Not, Which Is Disabled By Default. It Could Be Very Annoying And Frustrating To Manually Add Or Remove A Member Into A Group And The Automation To Revert The Changes Back Because The Member Does Not Match The Adding Or Match The Removing Criteria For The Automatic Group Members Management. Normally The IT Administrators Would Need To Check In The PS Module Configuration To Verify Whether An AD Group Is Automatically Managed Using The PSModule Before Membership Modification. This Might Lead To Failed Scheduled Tasks Due To Multiple PSSessions With The PSModule Loaded. From That Perspective "SnsPsAdGroupMembers" Stores A Predefined Constant Value In A Predefined AD Attribute Of The AD Managed Groups And Clears The Predefined Constant Value From The Predefined AD Attribute Of The Not Managed Groups. Therefore The Company IT Administrators Just Need To Look At That Attribute Before Manually Add Or Remove Groups Members In An AD Group.</maml:para>
      <maml:para>To Enable This Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet, To Specify An AD Attribute And A Constant Value Which Shall Be Set On The AD Managed Groups. To Disable That Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet To Clear Either The Value Or The AD Attribute Used By This Feature Or Both. When Enabled On A Scheduled Job After Actual Group Management "Invoke-SnsAdGroupMembersManage" Sets The Predefined Constant Value Into The Predefined AD Attribute Of All Enabled AD Managed Groups And Clears The Value From All Not Managed AD Groups. Therefore Once The Feature Is Disabled The User Have To Manually Clear The Value From The AD Attribute Of All The Groups In Case The Feature Was Ever Used. Changing The Attribute Will Not Clear The Value From The Old Attribute.</maml:para>
      <maml:para>NOTE: This Feature Considers As Managed Only The Groups That Are Enabled In The Groups Configuration. Disabling A Group From Automatic Members Management, Even Temporary Will Clear The AD Attribute Used By This Feature, Indicating To The Corporate IT Administrators, That The Group Membership Can Be Managed Manually.</maml:para>
      <maml:para>NOTE: This Feature Can Use Only AD Attributes With Type Of Single Valued String.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>Get-SnsAdManagedGroup Is Intended To Be Used Interactively By A User To Retrieve A Managed AD Group Configuration From The Configuration DataBase.</maml:para>
      <maml:para>NOTE: Please Make Sure That The PowerShell Is Closed, When You Finish With The Work On The Managed AD Groups Configuration. Otherwise Either The Other Users Or Any Automated Task Will Be Prevented From Work With The PSModule.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "BeginProcessing" Method "Get-SnsAdManagedGroup" CmdLet Initializes The PSModule Configuration. Verifies The Existence, The Schema And The Integrity Of The Configuration DataBase. Verifies About Other PowerShell Processes Using "SnsPsAdGroupMembers" PSModule.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "ProcessRecord" Method "Get-SnsAdManagedGroup" CmdLet Enumerates The Configuration Entries For Each Group Coming From The Pipeline Or Specified With "Identity" Parameter. If No Groups Are Specified Or Sent Through The Pipeline The CmdLet Enumerates All Enabled Managed AD Groups Configuration. The Add And Remove Logic Properties Are Normalized And The Matched AD Objects Are Verified Whether They Are Leavers If Any. The "Inclusions", "Exclusions" And "Notify" Properties Are Verified Whether They Contains Any Leavers. Then Each Individual Group Configuration Object Is Sent To The Pipeline.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The CmdLet Reverts SnsAdManagedGroup Objects With The Following Properties And Methods:</maml:para>
      <maml:para>- "Position" Property Of Type Integer. Represents The Group Position In The Collection For Members Management.</maml:para>
      <maml:para>- "Identity" Property Of Type Guid. Represents The Managed Group AD "objectGUID".</maml:para>
      <maml:para>- "Name" Property Of Type String. Contains The Value Of The Managed Group "cn" Attribute.</maml:para>
      <maml:para>- "AddLogic" Property Of Type String. Contains The Logic For Adding Members Into The Managed Group.</maml:para>
      <maml:para>- "RemoveLogic" Property Of Type String. Contains The Logic For Removing Members From The Managed Group.</maml:para>
      <maml:para>- "Inclusions" Property Of Type SnsAdManagedGroupInclusion Array. Contains An Array With The Group's Explicit Inclusions. Each SnsAdManagedGroupInclusion Object Contains: "Identity" Property Of Type Guid. "Name" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Exclusions" Property Of Type SnsAdManagedGroupExclusion Array. Contains An Array With The Group's Explicit Exclusions. Each SnsAdManagedGroupExclusion Object Contains: "Identity" Property Of Type Guid. "Name" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Notify" Property Of Type SnsAdManagedGroupContact Array. Contains An Array With The Group's Notification Contacts. Each SnsAdManagedGroupContact Object Contains: "Email" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Enabled" Property Of Type Boolean. Represents Whether The Managed Group Entry Is Active Or Not.</maml:para>
      <maml:para>- "GetSnsRawAddLogic" Method Intended To Revert The Not Normalized Add Logic As It Is Set In The Group Configuration.</maml:para>
      <maml:para>- "GetSnsRawRemoveLogic" Method Intended To Revert The Not Normalized Remove Logic As It Is Set In The Group Configuration.</maml:para>
    </maml:description>
    <command:syntax>
      <!-- Parameter set: __AllParameterSets -->
      <command:syntaxItem>
        <maml:name>Get-SnsAdManagedGroup</maml:name>
        <!-- Parameter: Identity -->
        <command:parameter required="false" globbing="false" pipelineInput="true (ByValue)" position="0" aliases="Group,ManagedGroup">
          <maml:name>Identity</maml:name>
          <maml:description>
            <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
            <maml:para>If Omitted The CmdLet Will Get All Managed Groups.</maml:para>
            <maml:para>The Parameter Accepts The Following Values:</maml:para>
            <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
            <maml:para>- objectGUID</maml:para>
            <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
            <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
            <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
            <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          </maml:description>
          <command:parameterValue required="true">object</command:parameterValue>
          <dev:type>
            <maml:name>System.Object</maml:name>
            <maml:uri />
          </dev:type>
        </command:parameter>
        <!-- Parameter: DomainController -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>DomainController</maml:name>
          <maml:description>
            <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
            <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
            <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
            <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
            <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
        <!-- Parameter: Force -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>Force</maml:name>
          <maml:description>
            <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
    <command:parameters>
      <!-- Parameter: Identity -->
      <command:parameter required="false" globbing="false" pipelineInput="true (ByValue)" position="0" aliases="Group,ManagedGroup">
        <maml:name>Identity</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para>If Omitted The CmdLet Will Get All Managed Groups.</maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="false" globbing="false" pipelineInput="true (ByValue)" position="0" aliases="Group,ManagedGroup">
        <maml:name>Group</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para>If Omitted The CmdLet Will Get All Managed Groups.</maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>This is an alias of the Identity parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="false" globbing="false" pipelineInput="true (ByValue)" position="0" aliases="Group,ManagedGroup">
        <maml:name>ManagedGroup</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para>If Omitted The CmdLet Will Get All Managed Groups.</maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>This is an alias of the Identity parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <!-- Parameter: DomainController -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>DomainController</maml:name>
        <maml:description>
          <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
          <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
          <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
          <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
          <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: Force -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>Force</maml:name>
        <maml:description>
          <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
        </maml:description>
        <command:parameterValue required="true">SwitchParameter</command:parameterValue>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
    </command:parameters>
    <command:inputTypes>
      <command:inputType>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para>If Omitted The CmdLet Will Get All Managed Groups.</maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
        </maml:description>
      </command:inputType>
    </command:inputTypes>
    <command:returnValues>
      <!-- OutputType: SnsAdManagedGroup -->
      <command:returnValue>
        <dev:type>
          <maml:name>SnsAdGroupMembers.SnsAdManagedGroup</maml:name>
          <maml:uri />
        </dev:type>
      </command:returnValue>
    </command:returnValues>
    <maml:alertSet>
      <maml:title></maml:title>
      <maml:alert>
        <maml:para>AUTHOR: Svetoslav Nedyalkov Savov</maml:para>
        <maml:para>THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK</maml:para>
        <maml:para>OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.</maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
      </maml:alert>
    </maml:alertSet>
    <command:examples>
      <command:example>
        <maml:title>---------- EXAMPLE 1 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Get-SnsAdManagedGroup -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Enumerates All Managed AD Group Configuration Objects From The PSModule Configuration.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 2 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Get-SnsAdManagedGroup -Identity "Finance Department DL";</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Enumerates The Configuration Object For AD Group "Finance Department DL".</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 3 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Get-SnsAdManagedGroup "Finance Department", "Sales Department";</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Enumerates The Configuration Objects For AD Groups "Finance Department" And "Sales Department".</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 4 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = "Finance Department DL", "Sales Department DL" | `
Get-SnsAdManagedGroup -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Enumerates The Configuration Objects For AD Groups "Finance Department DL" And "Sales Department DL".</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
    </command:examples>
    <maml:relatedLinks>
      <maml:navigationLink>
        <maml:linkText> svesavov / SnsPsAdGroupMembers - </maml:linkText>
        <maml:uri>https://github.com/svesavov/SnsPsAdGroupMembers</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> PowerShell Gallery - </maml:linkText>
        <maml:uri>https://www.powershellgallery.com/packages/SnsPsAdGroupMembers/</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> Svetoslav Savov on LinkedIn - </maml:linkText>
        <maml:uri>https://www.linkedin.com/in/svetoslavsavov</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> SQLite V3 - </maml:linkText>
        <maml:uri>https://sqlite.org/index.html</maml:uri>
      </maml:navigationLink>
    </maml:relatedLinks>
  </command:command>
  <!-- Cmdlet: New-SnsAdManagedGroup -->
  <command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
    <command:details>
      <command:name>New-SnsAdManagedGroup</command:name>
      <command:verb>New</command:verb>
      <command:noun>SnsAdManagedGroup</command:noun>
      <maml:description>
        <maml:para>Creates A Managed Active Directory Group Configuration Entry.</maml:para>
      </maml:description>
    </command:details>
    <maml:description>
      <maml:para>Creates A Managed Active Directory Group Configuration Entry.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Operation Of "SnsPsAdGroupMembers" PSModule Install It With "AllUsers" Scope. The Idea Behind This Module Is To Be Used On A Scheduled Task "As Service" For The Actual Group Members Management, And Interactively By IT Administrators To Create And Modify The Managed Groups Configuration. This Requires The PSModule To Be Available To Multiple User Accounts.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Creation Of "SnsPsAdGroupMembers" PSModule DataBases, The First Load Of The PSModule Must Be In Elevated Mode. In The Normal Operation The PSModule Does Not Require Elevated Mode. More Information About That Is Provided Further In This Document.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"Why Should I Use This PSModule Instead Of Dynamic Groups?":</maml:para>
      <maml:para>- Well First And Foremost Reason Is Related With The Fact That This PowerShell Module Does Allow To Have Different Logic For Adding And Removing Members. This Is Not Achievable With Dynamic Groups.</maml:para>
      <maml:para>- The Company IT Department Might Need To Use A Single Group For Granting Access Rights In On Premises AD, AzureAD And Use It As Distribution List At The Same Time. Although This Can Be Achieved With Dynamic Groups You Have To Maintain At Least Two Of Them, One For On Premises AD And One For AzureAD.</maml:para>
      <maml:para>- There Are Cases Related With Certain AzureAD Functionalities And Synchronizations With Third Party Cloud Solutions Which Do Not Support Nested And Dynamic Groups. Managing Of Groups With Large Number Of Members In Corporate Environment Without Using Of Group Nestling Could Be Quite Tricky And Related With Lot Of Users Frustration And Administrative Effort.</maml:para>
      <maml:para>- The "SnsPsAdGroupMembers" PSModule Prepare Reports About Modifying Group Members And Audit Of Changes In The Group Management Settings. Whenever A Group Is Used For Granting Sensitive Access Rights Or Managing The Members Of A Sensitive Distribution List, The Group Owners Might Want To Receive Those Reports, Often Immediately After The Above-Mentioned Actions Are Taken.</maml:para>
      <maml:para>- The PSModule Can Be Used Only For Adding Or Only For Removing Members. Using Of Both Is Not Mandatory. This Does Allow Implementation Of Process For Adding Members In Sensitive Groups, Like "Domain Admins" For Example, Following Formal Approval Process, But Removing Members Immediately When The Person Who Owns The Account Leave The Company, Or Change The Position. In This Case There Will Be Zero Tolerance For Users "Forgotten" With More Than Needed Access Rights.</maml:para>
      <maml:para>This PSModule Have The Same Disadvantages And Requirements As The Dynamic Groups. Since The Management Logic Is Based On AD Attribute Values, It Requires The Used Ones To Be Up To Date And Consistent. Some Sort Of Synchronization From The Company HR System Would Address This. Such A Synchronization Is Nice To Have But Not A Requirement. Using My Other PSModule's Will Be Relatively Easy Creation Of Own Synchronization Related With Any On Premises HR Application. Most Of The Cloud Based Ones, Already Have Out Of The Box Synchronization Tools. Creation Of New One Would Not Be Feasible, But It Depends On The API's The Tool Provides.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Manages The Membership Of Active Directory Groups In A Single Domain Forest Based On Predefined Logic About Adding And Removing Members. For That Purpose, The PowerShell Module Uses SQLite Configuration DataBase To Keep Information About:</maml:para>
      <maml:para>- The Managed Groups.</maml:para>
      <maml:para>- The Logic For Adding Members Into Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- The Logic For Removing Members From Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- Explicit Group Inclusions. Those Are AD Objects Which Shall Be Added As Group Members, Although They Do Not Meet The Adding Criteria.</maml:para>
      <maml:para>- Explicit Group Exclusions. Those Are AD Objects Which Shall Not Be Added As Group Members, Although They Do Meet The Adding Criteria.</maml:para>
      <maml:para>- Notification Contacts Who Shall Receive Reports About The Actions And Audit Events Related With Their Own Groups.</maml:para>
      <maml:para>- The PSModule Configuration.</maml:para>
      <maml:para>- Managed Groups Configuration Changes Tracking.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Uses Another SQLite DataBase To Store All The Events Related With The CmdLets Operation And Events Related With Actions Taken On The Managed Groups.</maml:para>
      <maml:para></maml:para>
      <maml:para>To Increase The Confidence In The Automation Among The Group Owners, "SnsPsAdGroupMembers" PSModule Produces Reports Intended To Be Provided To Those Owners, Whenever The PSModule Adds And / Or Removes Members, Whenever It Detects Changes In The Groups Configuration That Might Affect The Group Members, Such Like Changes In The Add Logic, Remove Logic, Explicit Inclusions, Explicit Exclusions And Notification Contacts.</maml:para>
      <maml:para>In Case Of Changes In The Notification Contacts, Both The Old And New Contacts Are Included In The Report Recipients List. The Reports Are Prepared Only When Actual Changes Are Made Or Detected Whenever The Actual Group Management Occur. For That Purpose, The PSModule Uses An SQLite Statistics DataBase To Store Information About:</maml:para>
      <maml:para>- Events Related With Automatic Adding Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Automatic Removing Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Changes In Managed Groups Configuration That Might Affect The Group Membership, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With The Module Operation And Groups Management Intended To Be Provided To The Company IT's. The Internal Events Not Related With Specific Managed Group Are Not Kept In The Statistics DataBase. Therefore The Statistics DataBase Is Not Suitable Source Of Information About Troubleshooting Of Performance, Module Related Issues, And Script Related Issues. However It Is Perfectly Reliable Source Of Troubleshooting Information Related With Troubleshooting Of Incorrect Logic And Any Managed Groups Misconfiguration.</maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Only Prepares Reports And Reverts Them As "SnsReportCollection" Output Object. The Email Relay Options Differ From One Environment To Another, It Is Not Feasible To Maintain Multiple Settings Related With Email Sending In The Configuration DataBase, While Sending Of An Email From PowerShell Is Simple As Running Of A CmdLet. Depending On The Company, Might Be Used Different Languages, Different Wording, Company Branding, Company Stationaries, Company Colors And Company Visual Stylings In The Emails. From That Perspective The PSModule Reverts Reports In Custom Objects And Collections. The User Have To Convert Them To HTML Text And Send Them As Emails, Within The Automation Scripts Which Use "SnsPsAdGroupMembers" Module. The Simplest Way For Doing That Is Using "ConvertTo-Html" And "Send-MailMessage" Native PowerShell CmdLets. Whenever Managed Group Owners Are Not Interested To Receive Any Notifications The Reports For They Own Groups Can Be Disabled Via Leaving Empty The Notification Contacts Setting Of The Group (Or Remove All Notification Contacts For A Managed Group If There Are Already Specified). This Does Not Disable The Logging Of Events Into The Statistics DataBase.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>For DataBase Engine Is Used SQLite. SQLite Is Free Open Source Serverless DataBase, Which Comes With Its Own Advantages And Disadvantages. As Serverless DataBase There Is No Server To Manage The DataBase Requests And Locks. From That Perspective Using A Single SQLite DataBase Either Over Network Or Mapped Drives Or Simultaneously By Multiple Applications / PSSessions Might Lead To Errors In Accessing The DataBase Or DataBase Corruption.</maml:para>
      <maml:para>From That Perspective All The CmdLets Within This Module Have A Feature That Prevents Running Of Those CmdLets In Multiple PowerShell Sessions. All The CmdLets Have Parameter "Force" Which Allows The Usage Of The CmdLets In Multiple PSSessions, Use It At Your Own Risk. The Parameter Is Ignored And Does Not Work When The PSSession Is "As A Service" (In Automation Script Executed With Scheduled Task For Example).</maml:para>
      <maml:para>Both The Configuration And Statistics DataBases Are Located In "C:\ProgramData\SnsAdGroupMembers" By Default. In Order The Folder And DataBase Files To Be Created Properly, The First Run Of This CmdLet To Be Made In Elevated PowerShell Session. Creation Of The DataBase Folder And Setting The Required NTFS Permissions Requires Local Administrator Access Rights. The DataBase Files Can Be Moved / Migrated Into Different Folders, In That Case The Administrator Who Is Doing That Have To Make Sure That The Folder Exists, All The Users That Will Use This PSModule Will Have "Modify" NTFS Permissions Over The Folder And The DataBase Files, Move The DataBase Files Into The New Folder And Properly Provide The Module With The New Folder Absolute (Full) Path.</maml:para>
      <maml:para>Although Using This PSModule On Domain Controllers Is Possible, It Is Against The Best Practices And It Is Not Recommended. All Automations Shall Be Run On Dedicated Virtual Or Physical Machine. From That Perspective It Is Required "Local Admin" Access Rights.</maml:para>
      <maml:para>It Is Not Recommended The DataBase Files To Be Moved, And If That Happen They Shall Be Not Moved On Network Shares Or Mapped Drives. This Will Not Prevent The PSModule To Do Its Job. It Will Introduce Performance Degradation, Possible Interruption In Case Of Network Issues And Eventually Corruption Of The DataBases.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>Never Move DataBases Outside The Default Location When The PSModule Is Installed With Scope "CurrentUser".</maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>"CfgDbFolder" Setting Specifies The Location Of Both Configuration And Statistics DataBases Simultaneously Unless The Statistics DataBase Have Explicitly Specified Location. With Other Words When Modify Configuration DataBase Location And "StatDbFolder" Setting Is Not Used, Both DataBases Have To Be Moved In The New Location.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Contains CmdLets Intended To Be Run Interactively By The User And CmdLets Intended To Be Run Within Automation Scripts On A Schedule As A Service. The CmdLets Intended To Be Used Within Automation Scripts Comply With Additional Requirements Related With Logging, Reporting And Ability To Being Monitored (Using "SnsPsScriptsMonitoring" PSModule For Example). "Invoke-SnsAdGroupMembersManage" Is A CmdLet Intended To Be Used In An Automation Scripts. By Its Nature, This CmdLet Is An Automation Encapsulated Within A CmdLet. The Logs And Events Happening During The CmdLet Run Are Logged In An SQLite DataBase "GroupMembersProvStat.db" Referred Furter As Statistics DataBase. It Could Be Used For Other Reporting Purposes Like Periodical Comprehensive Reports About The Actions Taken By Automation Scripts (This Requires Additional Scripting To Read The DataBase And Prepare The Reports).</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>When Working With Active Directory It Is Important What Identity Attribute Will Be Chosen For Binding To The AD Objects. Although Naturally AD Uses DistinguishedName For Binding And LDAP Queries, It Is Not The Best Possible Identity. The DistinguishedName Is Unique But It Is Not Constant, It Can Be Changed Over The AD Object Life Cycle. An AD Object Can Be Renamed And / Or Moved Into Different Organizational Unit, Or The Organizational Unit Where The Object Is Located Can Be Renamed And / Or Moved. That Will Modify Object's Distinguished Name. In This Case The Active Directory Will Automatically Reflect Those Changes In The Attributes Of The Object And On All Relational Attributes Of The Remaining Objects Which Point To Our Object. For Example "member" Attribute Of All The Groups Where Our AD Object Is Member Of, Or "manager" Attribute Of All Accounts That Our User Is Manager. However AD Will Not Modify Accordingly The PSModule Configuration Stored In An External For The AD DataBase. This Will Lead To Errors And Failures.</maml:para>
      <maml:para>It Is Best Practice The AD Related Applications To Use For Binding Other Identity Attributes Which Do Not Change During The Objects Life Cycle. Those Are "objectGUID" And "objectSid". The Best Practices Gives Preference To The "objectSid" By Various Reasons. Since It Is Possible Groups To Have Member Objects Without "objectSid" (Contact Objects For Example) The "SnsPsAdGroupMembers" PSModule Uses As Identity The "ObjectGUID" Attribute. Thus Way When An Object Is Renamed Or Moved The PSModule Is Not Affected And Continue To Work As Intended.</maml:para>
      <maml:para>The The Well-Known AD Behavior, That When An Object Is Deleted And Then Recreated, All The Access Rights And Group Membership Are Lost, Is Related With The Fact That The Recreated Object Have Different "objectSid". Using The "objectGUID" As Identity Introduces Similar Behavior Of "SnsPsAdGroupMembers". Deletion And Recreation Of An AD Group Object Does Not Automatically Enable It For Automatic Members Management With The Logic Of The Deleted Group.</maml:para>
      <maml:para>The Using "objectGUID" As Identity In The PSModule Configuration Ensures That The PSModule Is Not Affected By Objects Rename Or Objects Move. When A Managed Group, Explicit Inclusion, Explicit Exclusion Is Renamed Or Moved Into Different OU, Their "objectGUID" Remains Intact. And The PSModule Continue To Bind To Those Objects Without Errors. However This Does Introduce Additional Overhead For The CmdLets Intended To Manage The Groups Configuration. When An Object Is Provided To Them They Need To Search For That Object In Active Directory, Enumerate The "objectGUID" Of The Object And Specify The Enumerated Value Into The Configuration DataBase. Since The CmdLets Query AD, That Query Can Be Made Against Multiple Attributes, Which Does Provide Freedom For The User To Use Multitude Of Values When An AD Object Is Provided To A Parameter. Please Refer To Each To The Parameters Sections Of Each CmdLet Help Document.</maml:para>
      <maml:para>When LDAP Queries Are Needed The Things Get More Complicated. The LDAP Queries Work Only With DistinguishedName. When You Need To Query About Reports Of A Person, Or Members Of A Group The AD Expects LDAP Query With DistinguishedName Values. An Example Of Often Use LDAP Query Clause Is:</maml:para>
      <maml:para>"(manager=CN=Jane Smith,CN=Users,DC=contoso,DC=com)"</maml:para>
      <maml:para>If "SnsPsAdGroupMembers" PSModule Keep It As Is Into The Configuration, In Case Of DistinguishedName Change, The Logic Will Revert No Results, Which Might Lead To Removal Of All The Members From The Group. Instead The LDAP Clause Is Stored Like:</maml:para>
      <maml:para>"(manager=00000000-0000-0000-0000-000000000000)"</maml:para>
      <maml:para>This Complicates The PSModule Further, As On The AD Managed Group Configuration Creation / Modification It Have To Evaluate The Specified Parameters, Match Them Using RegEx Pattern About Any Distinguished Names, Bind To The AD Object Using The Matched DistinguishedName, Enumerates The AD Object "objectGUID" And Amend The Matched DistinguishedName With The Enumerated "objectGUID". And Before The Actual AD Managed Group Members Management, It Have To Evaluate The Configuration About "objectGUID" Values Using RegEx Matching, Bind To The AD Object Using The Matched "objectGUID", Enumerate The AD Object DistinguishedName And Amend The "objectGUID" With The Enumerated DistinguishedName. Thus Way Introducing Overhead For The PSModule And For The Domain Controller Which Serves The LDAP Requests.</maml:para>
      <maml:para>To Reduce The Number Of The AD Requests And The Overhead, The PSModule Caches The Attributes Of The Previously Bind To Or Queried About AD Objects, And Consequently Uses The Cache Instead Of Making New AD Requests. The Effectiveness Of The AD Cache Depends On The Similarities In The Configuration Of The Groups.</maml:para>
      <maml:para>The Attributes Modified By The "SnsPsAdGroupMembers" PSModule Like "memberOf" AD Attribute, Are Never Cached. Caching Those Might Lead To False Positive Or Real Errors.</maml:para>
      <maml:para>The Values Of The AD Attributes Without Requirements For Uniqueness Cannot Be Used For Indexing And Searches In The Cache. For Example There Is No Uniqueness Requirement For "cn" Attribute, You Can Have Multiple Objects With The Same "cn" As Long As They Are Located In Different OU's. When A CmdLet Parameter From The PSModule Is Provided With "cn" Value, It Must Make LDAP Search To Enumerate The AD Object, Either To Confirm That The Value Corresponds To An AD Object Or To Throw Error About Multiple Objects. In Case We Have The Specified Value In The Cache It Is Not Certain That There Are No Other Objects With The Same Value In The AD Domain. Whenever We Use AD Attributes With Uniqueness Requirements Like Distinguished Name, For Example Presence Of The Provided Value In The Cache Can Be Safely Assumed As Correct And Unique, In That Case Query Against The AD Domain Is Not Needed. Usage Of Values In Attributes Without Uniqueness Requirements Reduces The Effectiveness Of The AD Cache Feature Further.</maml:para>
      <maml:para>Introducing A Cache In The PSModule Introduces All Generic Disadvantages Related With Caching, Like Cached Outdated Values. The "SnsPsAdGroupMembers" PSModule Keeps The AD Cache In The System Memory. This Does Ensure Maximum Speed For Accessing The Cache, With Negative Impact On The Machine Performance Because Of The Increased Memory Usage. Together With The Feature Which Does Not Allow Usage Of The PSModule In Multiple PSSession (Which Actually Force The Users To Close Their PSSessions Once They Finish Their Job), Ensures Relatively Short Life Span Of The Cached Entries, Thus Way Reducing The Cache Effectiveness But Increasing The Reliability Via Minimizing The Possibility For Issues Related With Outdated Entries.</maml:para>
      <maml:para>Although The Shorter Lifespan Of The Cached Entries Reduces The Possibility For Mistakes, It Does Not Eliminate Them Completely. Mistakes Might Happen Without Corrupted Or Outdated Cached Entry. Let Us Assume We Have A Department Related Group Where Members Are Added Based On Specific Value In The Department AD Attribute And Removed When The Value Is Different. At The Same Time, The Department AD Attribute Is Automatically Synchronized From The Company HR System. In Case Of Department Rebranding The Sync From The HR System Will Modify The Attribute Value Of All Department Members. In That Case All The Department Members Will Be Removed From The Group. This Is Addressed With Introducing Of New Feature Which Prevents Any Members Removal Whenever The Members Enumerated For Removing Are More Than Certain Threshold. The Threshold Is Configurable. The Default Value Is 50%.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" Provides A Feature Intended For Quick Identifying Whether A Group Is Automatically Managed Or Not, Which Is Disabled By Default. It Could Be Very Annoying And Frustrating To Manually Add Or Remove A Member Into A Group And The Automation To Revert The Changes Back Because The Member Does Not Match The Adding Or Match The Removing Criteria For The Automatic Group Members Management. Normally The IT Administrators Would Need To Check In The PS Module Configuration To Verify Whether An AD Group Is Automatically Managed Using The PSModule Before Membership Modification. This Might Lead To Failed Scheduled Tasks Due To Multiple PSSessions With The PSModule Loaded. From That Perspective "SnsPsAdGroupMembers" Stores A Predefined Constant Value In A Predefined AD Attribute Of The AD Managed Groups And Clears The Predefined Constant Value From The Predefined AD Attribute Of The Not Managed Groups. Therefore The Company IT Administrators Just Need To Look At That Attribute Before Manually Add Or Remove Groups Members In An AD Group.</maml:para>
      <maml:para>To Enable This Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet, To Specify An AD Attribute And A Constant Value Which Shall Be Set On The AD Managed Groups. To Disable That Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet To Clear Either The Value Or The AD Attribute Used By This Feature Or Both. When Enabled On A Scheduled Job After Actual Group Management "Invoke-SnsAdGroupMembersManage" Sets The Predefined Constant Value Into The Predefined AD Attribute Of All Enabled AD Managed Groups And Clears The Value From All Not Managed AD Groups. Therefore Once The Feature Is Disabled The User Have To Manually Clear The Value From The AD Attribute Of All The Groups In Case The Feature Was Ever Used. Changing The Attribute Will Not Clear The Value From The Old Attribute.</maml:para>
      <maml:para>NOTE: This Feature Considers As Managed Only The Groups That Are Enabled In The Groups Configuration. Disabling A Group From Automatic Members Management, Even Temporary Will Clear The AD Attribute Used By This Feature, Indicating To The Corporate IT Administrators, That The Group Membership Can Be Managed Manually.</maml:para>
      <maml:para>NOTE: This Feature Can Use Only AD Attributes With Type Of Single Valued String.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>New-SnsAdManagedGroup Is Intended To Be Used Interactively By A User To Create A Managed AD Group Configuration Entry In The Configuration DataBase.</maml:para>
      <maml:para>NOTE: Please Make Sure That The PowerShell Is Closed, When You Finish With The Work On The Managed AD Groups Configuration. Otherwise Either The Other Users Or Any Automated Task Will Be Prevented From Work With The PSModule.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In Parameters Validation The CmdLet Query The Active Directory And Enumerates The Provided By The User Objects. In Case The Specified Objects Does Not Exists The CmdLet Throws Error. The Parameters Which Accept Wildcard Usage Requires To Identify Unambiguously The Specified Object In AD. Therefore If A Specified Wildcard Pattern Revert More Than One Object, The CmdLet Will Throw Error. Use The Wildcards Only To Spare Typing When You Are Completely Sure It Will Revert Single Object.</maml:para>
      <maml:para>The Validation Of "AddLogic" And "RemoveLogic" Parameters, Treat The Specified Values As LDAP Query And Executes Them Against AD. If The LDAP Query Revert No Results The Validation Fails. This Reduces The CmdLet Performance And Slows It Down, But It Is Not Intended To Be Used On Regular Basis Or Within Automation Scripts Anyway. So The Reduced Performance Is Acceptable In This Case. When The CmdLet Connects To A Domain Controller In The Same Subnet The Reduced Performance Is Not Noticeable By The User.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "BeginProcessing" Method "New-SnsAdManagedGroup" CmdLet Initializes The PSModule Configuration. Verifies The Existence, The Schema And The Integrity Of The Configuration DataBase. Verifies About Other PowerShell Processes Using "SnsPsAdGroupMembers" PSModule.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "ProcessRecord" Method "New-SnsAdManagedGroup" CmdLet Performs Additional Verifications Which Cannot Be Made During The Parameters Validation. "AddLogic" And "RemoveLogic" Parameters Are Not Mandatory To Allow The User To Configure A Group Only For Adding Or Only For Removing Members, However Where Both Are Missing The Group Will Be Not Managed At All. Normally This Cannot Be Verified During The Parameters Validation As The CmdLet Accepts The Parameters In The Order Specified By The User. Therefore The User Might Specify The "RemoveLogic" Before The "AddLogic" Which Will Cause False Positives On Any Parameter Validation From This Kind. Afterward The CmdLet Enumerates The Values For The Parameters Which Are Required For The Normal Operation Of The PSModule But Are Not Specified By The User. One Of Those Is The Order Position Of The New AD Managed Group Entry. Whenever The "Position" Parameter Is Omitted The New AD Managed Group Entry Will Be Created With A Position Value Which Will Cause The Group To Be Processed By "Invoke-SnsAdGroupMembersManage" CmdLet After The Existing AD Managed Groups. (The New Group Will Be Placed At The End Of The Queue). Then The CmdLet Creates The Main AD Managed Group Entry, And Afterward Invokes In Background The CmdLets For Setting Exclusions, Inclusions And Notification Contacts. I've Included Those Parameters To This CmdLet Just To Allow Mass Creation Of AD Managed Groups Using Input From .CSV File Or Excel File Converted To .CSV File, Without The Need Of Writing A Complex Script. This Is The Reason The Corresponding Parameters To Accept Only String Values, Unlike The Dedicated For That Purpose CmdLets. At The End, The Newly Created AD Managed Group Is Retrieved From The Configuration, Its Properties Normalized And Send To The Pipeline Output.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The CmdLet Reverts SnsAdManagedGroup Objects With The Following Properties And Methods:</maml:para>
      <maml:para>- "Position" Property Of Type Integer. Represents The Group Position In The Collection For Members Management.</maml:para>
      <maml:para>- "Identity" Property Of Type Guid. Represents The Managed Group AD "objectGUID".</maml:para>
      <maml:para>- "Name" Property Of Type String. Contains The Value Of The Managed Group "cn" Attribute.</maml:para>
      <maml:para>- "AddLogic" Property Of Type String. Contains The Logic For Adding Members Into The Managed Group.</maml:para>
      <maml:para>- "RemoveLogic" Property Of Type String. Contains The Logic For Removing Members From The Managed Group.</maml:para>
      <maml:para>- "Inclusions" Property Of Type SnsAdManagedGroupInclusion Array. Contains An Array With The Group's Explicit Inclusions. Each SnsAdManagedGroupInclusion Object Contains: "Identity" Property Of Type Guid. "Name" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Exclusions" Property Of Type SnsAdManagedGroupExclusion Array. Contains An Array With The Group's Explicit Exclusions. Each SnsAdManagedGroupExclusion Object Contains: "Identity" Property Of Type Guid. "Name" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Notify" Property Of Type SnsAdManagedGroupContact Array. Contains An Array With The Group's Notification Contacts. Each SnsAdManagedGroupContact Object Contains: "Email" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Enabled" Property Of Type Boolean. Represents Whether The Managed Group Entry Is Active Or Not.</maml:para>
      <maml:para>- "GetSnsRawAddLogic" Method Intended To Revert The Not Normalized Add Logic As It Is Set In The Group Configuration.</maml:para>
      <maml:para>- "GetSnsRawRemoveLogic" Method Intended To Revert The Not Normalized Remove Logic As It Is Set In The Group Configuration.</maml:para>
    </maml:description>
    <command:syntax>
      <!-- Parameter set: __AllParameterSets -->
      <command:syntaxItem>
        <maml:name>New-SnsAdManagedGroup</maml:name>
        <!-- Parameter: Identity -->
        <command:parameter required="true" globbing="false" pipelineInput="true (ByPropertyName)" position="named" aliases="Group,ManagedGroup">
          <maml:name>Identity</maml:name>
          <maml:description>
            <maml:para>Specifies A Not Managed Active Directory Group.</maml:para>
            <maml:para></maml:para>
            <maml:para>The Parameter Accepts The Following Values:</maml:para>
            <maml:para>- SMTP Email Address. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- Exchange Alias. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- cn. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- distinguishedName. Must Be Existing Group In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
            <maml:para>- displayName. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- name. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- sAMAccountName. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- objectGUID. Must Be Existing Group In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
            <maml:para>- objectSid. Must Be Existing Group In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
        <!-- Parameter: AddLogic -->
        <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named">
          <maml:name>AddLogic</maml:name>
          <maml:description>
            <maml:para>Specifies The Logic For Adding Members Of The AD Managed Group.</maml:para>
            <maml:para>The Logic Is Active Directory Attributes Based And Must Comply With The Lightweight Directory Access Protocol (LDAP) Query Language.</maml:para>
            <maml:para>For Best Results I Would Recommend Usage Of Attributes Which Values Are Automatically Maintained, For Example With A Synchronization From An HR Tool.</maml:para>
            <maml:para></maml:para>
            <maml:para></maml:para>
            <maml:para>The Provided Value Will Be Used On The Group Members Adding As Follows:</maml:para>
            <maml:para>"(&amp;(objectCategory=person)(objectClass=user)(!(memberOf=[ADManagedGroupDn]))[AddLogic])"</maml:para>
            <maml:para>During The Parameter Validation The CmdLet Will Actually Execute The Following LDAP Query:</maml:para>
            <maml:para>"(&amp;(objectCategory=person)(objectClass=user)[AddLogic])"</maml:para>
            <maml:para>Therefore The Value Specified To The Parameter Must Have The Following Syntax "([Attribute1]=[Value1])"</maml:para>
            <maml:para></maml:para>
            <maml:para>Whenever You Need To Specify Multiple Conditions And The Added Member Must Comply With All Of Them (AND Logic) You Need Not To Specify AND. The Logic Must Looks Like "([Attribute1]=[Value1])([Attribute2]=[Value2])".</maml:para>
            <maml:para>For Example When You Need All Enabled Users With Mailboxes From "Finance Department" To Be Added In A Group The Logic Has To Looks Like:</maml:para>
            <maml:para>"(department=Finance Department)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)"</maml:para>
            <maml:para></maml:para>
            <maml:para>Whenever You Need To Specify Multiple Conditions With OR Logic. You Need To Specify That. The Logic Must Looks Like "(|([Attribute1]=[Value1])([Attribute2]=[Value2]))".</maml:para>
            <maml:para>For Example When You Need All Enabled Users With Mailboxes From "Finance Department" And "Sales Department" To Be Added In A Group The Logic Has To Looks Like:</maml:para>
            <maml:para>"(|(department=Finance*)(department=Sales*))(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)"</maml:para>
            <maml:para></maml:para>
            <maml:para></maml:para>
            <maml:para>To Save You Time Researching In Internet About The Correct Syntax For Reference LDAP extensibleMatch Rules OID's When They Are Needed, You Can Use:</maml:para>
            <maml:para>- :Band: When You Need LDAP_MATCHING_RULE_BIT_AND (:1.2.840.113556.1.4.803:)</maml:para>
            <maml:para>- :Bor: When You Need LDAP_MATCHING_RULE_BIT_OR (:1.2.840.113556.1.4.804:)</maml:para>
            <maml:para>- :Expand: When You Need LDAP_MATCHING_RULE_TRANSITIVE_EVAL (:1.2.840.113556.1.4.1941:)</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
        <!-- Parameter: Contact -->
        <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named" aliases="NotificationContact,Email,Mail">
          <maml:name>Contact</maml:name>
          <maml:description>
            <maml:para>Specifies Recipients For The Group Related Audit Reports.</maml:para>
            <maml:para></maml:para>
            <maml:para>The Parameter Accepts The Following Values:</maml:para>
            <maml:para>- SMTP Email Address. Can Be Used For External Recipients. Does Not Support Wildcard Characters.</maml:para>
            <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
            <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
            <maml:para></maml:para>
            <maml:para>In Case Multiple Values Are Specified All Specified Contacts Will Be Added To The Specified Group.</maml:para>
            <maml:para>The Parameter Have Functionality Different Than The Recommendations And The Best Practices. The Parameter Accepts Only Values Of Types String Or String Array. Normally For Management Of The Notification Contacts Have To Be Used The CmdLets With Noun "SnsAdManagedGroupContact", Their Parameters Behave According The Best Practices And The MS Recommendations For CmdLet Parameters. I've Included This Parameter Here To Simplify The AD Managed Group Configuration Creation Using A .CSV File Or Excel File Converted To .CSV File. All The Objects Created With "Import-Csv" CmdLet Have Properties Of Type String. Type Of String Array By Default Is Not Available, Without Additional Processing Of The CmdLet Output Objects. From That Perspective This Parameter Can Accept Single String Value And Splits It To String Array On Semicolon (;) And Comma (,) Characters, Assuming That There Will Be No AD Objects Containing Those Characters In The Attributes Used As Identity. To Avoid Issues With The Input Objects Created By "Import-Csv" CmdLet Please Avoid Using Those Characters As .CSV Delimiter And Make Sure The Quotation Marks (") In The .CSV File Are In Their Proper Place.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string[]</command:parameterValue>
          <dev:type>
            <maml:name>System.String[]</maml:name>
            <maml:uri />
          </dev:type>
        </command:parameter>
        <!-- Parameter: Disabled -->
        <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named">
          <maml:name>Disabled</maml:name>
          <maml:description>
            <maml:para>Specifies To Disable The New AD Managed Group Configuration Entry.</maml:para>
            <maml:para>Disabled AD Managed Groups Are Not Processed By "Invoke-SnsAdGroupMembersManage".</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
        <!-- Parameter: DomainController -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>DomainController</maml:name>
          <maml:description>
            <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
            <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
            <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
            <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
            <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
        <!-- Parameter: Exclusion -->
        <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named" aliases="ExplicitExclusion">
          <maml:name>Exclusion</maml:name>
          <maml:description>
            <maml:para>Specifies An AD Object To Be Set In The List Of The Specified Managed Group Explicit Exclusions.</maml:para>
            <maml:para>Explicit Exclusions Are Used When We Need To Not Add As Group Member An AD Object Which Does Match The AddLogic.</maml:para>
            <maml:para></maml:para>
            <maml:para>The Parameter Accepts The Following Values:</maml:para>
            <maml:para>- SMTP Email Address. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
            <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
            <maml:para></maml:para>
            <maml:para>In Case Multiple Values Are Specified All Specified Exclusions Will Be Added To The Specified Group.</maml:para>
            <maml:para>The Parameter Have Functionality Different Than The Recommendations And The Best Practices. The Parameter Accepts Only Values Of Types String Or String Array. Normally For Management Of The Explicit Exclusions Have To Be Used The CmdLets With Noun "SnsAdManagedGroupExclusion", Their Parameters Behave According The Best Practices And The MS Recommendations For CmdLet Parameters. I've Included This Parameter Here To Simplify The AD Managed Group Configuration Creation Using A .CSV File Or Excel File Converted To .CSV File. All The Objects Created With "Import-Csv" CmdLet Have Properties Of Type String. Type Of String Array By Default Is Not Available, Without Additional Processing Of The CmdLet Output Objects. From That Perspective This Parameter Can Accept Single String Value And Splits It To String Array On Semicolon (;) And Comma (,) Characters, Assuming That There Will Be No AD Objects Containing Those Characters In The Attributes Used As Identity. To Avoid Issues With The Input Objects Created By "Import-Csv" CmdLet Please Avoid Using Those Characters As .CSV Delimiter And Make Sure The Quotation Marks (") In The .CSV File Are In Their Proper Place.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string[]</command:parameterValue>
          <dev:type>
            <maml:name>System.String[]</maml:name>
            <maml:uri />
          </dev:type>
        </command:parameter>
        <!-- Parameter: Force -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>Force</maml:name>
          <maml:description>
            <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
        <!-- Parameter: Inclusion -->
        <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named" aliases="ExplicitInclusion">
          <maml:name>Inclusion</maml:name>
          <maml:description>
            <maml:para>Specifies An AD Object To Be Set In The List Of The Specified Managed Group Explicit Inclusions.</maml:para>
            <maml:para>Explicit Inclusions Are Used When We Need To Add An AD Object Which Do Not Match The AddLogic As Group Member.</maml:para>
            <maml:para>Explicit Inclusion Objects External For The AD Domain Are Not Allowed.</maml:para>
            <maml:para></maml:para>
            <maml:para>The Parameter Accepts The Following Values:</maml:para>
            <maml:para>- SMTP Email Address. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
            <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
            <maml:para></maml:para>
            <maml:para>In Case Multiple Values Are Specified All Specified Inclusions Will Be Added To The Specified Group.</maml:para>
            <maml:para></maml:para>
            <maml:para>The Parameter Have Functionality Different Than The Recommendations And The Best Practices. The Parameter Accepts Only Values Of Types String Or String Array. Normally For Management Of The Explicit Inclusions Have To Be Used The CmdLets With Noun "SnsAdManagedGroupInclusion", Their Parameters Behave According The Best Practices And The MS Recommendations For CmdLet Parameters. I've Included This Parameter Here To Simplify The AD Managed Group Configuration Creation Using A .CSV File Or Excel File Converted To .CSV File. All The Objects Created With "Import-Csv" CmdLet Have Properties Of Type String. Type Of String Array By Default Is Not Available, Without Additional Processing Of The CmdLet Output Objects. From That Perspective This Parameter Can Accept Single String Value And Splits It To String Array On Semicolon (;) And Comma (,) Characters, Assuming That There Will Be No AD Objects Containing Those Characters In The Attributes Used As Identity. To Avoid Issues With The Input Objects Created By "Import-Csv" CmdLet Please Avoid Using Those Characters As .CSV Delimiter And Make Sure The Quotation Marks (") In The .CSV File Are In Their Proper Place.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string[]</command:parameterValue>
          <dev:type>
            <maml:name>System.String[]</maml:name>
            <maml:uri />
          </dev:type>
        </command:parameter>
        <!-- Parameter: Position -->
        <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named" aliases="OrderPosition">
          <maml:name>Position</maml:name>
          <maml:description>
            <maml:para>Specifies The Position For The New AD Managed Group.</maml:para>
            <maml:para>If Omitted The CmdLet Will Assign The Next Value After The Highest Existing Position In The Configuration, Placing The Newly Created Entry In The End Of The Processing Queue.</maml:para>
            <maml:para>"Invoke-SnsAdGroupMembersManage" CmdLet Process The AD Managed Groups In Ascending Order (In Sequence) Based On The AD Managed Group Position. Whenever There Are Dependencies Between The Groups, The Prerequisite Group Have To Be Processed Before The Dependent Group (Must Have Lesser Position). Otherwise The Dependent Group Will Use As Input Outdated Information.</maml:para>
            <maml:para>This Is Not Critical Though On The Next Run The Dependent Groups Will Have The Proper Input Because The Prerequisite Group Will Be Updated (On The Current Run). Wrong Sequence Just Slows Down The Group Members Management.</maml:para>
          </maml:description>
          <command:parameterValue required="true">int</command:parameterValue>
          <dev:type>
            <maml:name>System.Int32</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>-1</dev:defaultValue>
        </command:parameter>
        <!-- Parameter: RemoveLogic -->
        <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named">
          <maml:name>RemoveLogic</maml:name>
          <maml:description>
            <maml:para>Specifies The Logic For Removing Members From The AD Managed Group.</maml:para>
            <maml:para>The Logic Is Active Directory Attributes Based And Must Comply With The Lightweight Directory Access Protocol (LDAP) Query Language.</maml:para>
            <maml:para>For Best Results I Would Recommend Usage Of Attributes Which Values Are Automatically Maintained, For Example With A Synchronization From An HR Tool.</maml:para>
            <maml:para></maml:para>
            <maml:para></maml:para>
            <maml:para>The Provided Value Will Be Used On The Group Members Removing As Follows:</maml:para>
            <maml:para>"(&amp;[RemoveLdapQuery](memberOf=[ADManagedGroupDn]))"</maml:para>
            <maml:para>During The Parameter Validation The CmdLet Will Actually Execute The Following LDAP Query:</maml:para>
            <maml:para>"(&amp;(objectCategory=person)(objectClass=user)[RemoveLdapQuery])"</maml:para>
            <maml:para></maml:para>
            <maml:para>Unlike The AddLogic Here You Most Likely Will Need To Use OR Logic Only. Therefore You Need To Specify The Logic As Follows:</maml:para>
            <maml:para>"(|(!(Attribute1=Value1))(!(Attribute2=Value2)))"</maml:para>
            <maml:para></maml:para>
            <maml:para>For Example When You Need To Remove Users From A Group:</maml:para>
            <maml:para>- When They Are No Longer In "Finance Department" Or "Sales Department".</maml:para>
            <maml:para>- When Their Accounts Get Disabled.</maml:para>
            <maml:para>- When Their Mailboxes Are Disabled.</maml:para>
            <maml:para>"(|(!(|(department=Finance*)(department=Sales*)))(userAccountControl:1.2.840.113556.1.4.803:=2)(!(mail=*)))"</maml:para>
            <maml:para>For RemoveLogic It Just Does Not Make Sense To Use AND Logic. At The End We Need To Remove The Members When One Of The Conditions Occur. It Is Not Likely All Of The Conditions To Occur Simultaneously To Remove A Member.</maml:para>
            <maml:para>NOTE: Unlike The AddLogic The RemoveLogic Actually Does Not Add The Conditions The Removed Object To Be A User Account. Which Means That "SnsPsAdGroupMembers" PSModule Actually Does Remove Group And Contact Member Objects. When You Prepare Your RemoveLogic Please Pay Attention That The Different AD Objects Have Different Sets Of Attributes. For Example If You Have Condition (!(userPrincipalName=*)) This Would Automatically Remove All The Nested Groups And Contacts, Because They Have No UPN Attribute.</maml:para>
            <maml:para></maml:para>
            <maml:para></maml:para>
            <maml:para>To Save You Time Researching In Internet About The Correct Syntax For Reference LDAP extensibleMatch Rules OID's When They Are Needed, You Can Use:</maml:para>
            <maml:para>- :Band: When You Need LDAP_MATCHING_RULE_BIT_AND (:1.2.840.113556.1.4.803:)</maml:para>
            <maml:para>- :Bor: When You Need LDAP_MATCHING_RULE_BIT_OR (:1.2.840.113556.1.4.804:)</maml:para>
            <maml:para>- :Expand: When You Need LDAP_MATCHING_RULE_TRANSITIVE_EVAL (:1.2.840.113556.1.4.1941:)</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
    <command:parameters>
      <!-- Parameter: Identity -->
      <command:parameter required="true" globbing="false" pipelineInput="true (ByPropertyName)" position="named" aliases="Group,ManagedGroup">
        <maml:name>Identity</maml:name>
        <maml:description>
          <maml:para>Specifies A Not Managed Active Directory Group.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- distinguishedName. Must Be Existing Group In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- displayName. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Group In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Group In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="true (ByPropertyName)" position="named" aliases="Group,ManagedGroup">
        <maml:name>Group</maml:name>
        <maml:description>
          <maml:para>Specifies A Not Managed Active Directory Group.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- distinguishedName. Must Be Existing Group In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- displayName. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Group In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Group In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>This is an alias of the Identity parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="true (ByPropertyName)" position="named" aliases="Group,ManagedGroup">
        <maml:name>ManagedGroup</maml:name>
        <maml:description>
          <maml:para>Specifies A Not Managed Active Directory Group.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- distinguishedName. Must Be Existing Group In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- displayName. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Group In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Group In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>This is an alias of the Identity parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: AddLogic -->
      <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named">
        <maml:name>AddLogic</maml:name>
        <maml:description>
          <maml:para>Specifies The Logic For Adding Members Of The AD Managed Group.</maml:para>
          <maml:para>The Logic Is Active Directory Attributes Based And Must Comply With The Lightweight Directory Access Protocol (LDAP) Query Language.</maml:para>
          <maml:para>For Best Results I Would Recommend Usage Of Attributes Which Values Are Automatically Maintained, For Example With A Synchronization From An HR Tool.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
          <maml:para>The Provided Value Will Be Used On The Group Members Adding As Follows:</maml:para>
          <maml:para>"(&amp;(objectCategory=person)(objectClass=user)(!(memberOf=[ADManagedGroupDn]))[AddLogic])"</maml:para>
          <maml:para>During The Parameter Validation The CmdLet Will Actually Execute The Following LDAP Query:</maml:para>
          <maml:para>"(&amp;(objectCategory=person)(objectClass=user)[AddLogic])"</maml:para>
          <maml:para>Therefore The Value Specified To The Parameter Must Have The Following Syntax "([Attribute1]=[Value1])"</maml:para>
          <maml:para></maml:para>
          <maml:para>Whenever You Need To Specify Multiple Conditions And The Added Member Must Comply With All Of Them (AND Logic) You Need Not To Specify AND. The Logic Must Looks Like "([Attribute1]=[Value1])([Attribute2]=[Value2])".</maml:para>
          <maml:para>For Example When You Need All Enabled Users With Mailboxes From "Finance Department" To Be Added In A Group The Logic Has To Looks Like:</maml:para>
          <maml:para>"(department=Finance Department)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)"</maml:para>
          <maml:para></maml:para>
          <maml:para>Whenever You Need To Specify Multiple Conditions With OR Logic. You Need To Specify That. The Logic Must Looks Like "(|([Attribute1]=[Value1])([Attribute2]=[Value2]))".</maml:para>
          <maml:para>For Example When You Need All Enabled Users With Mailboxes From "Finance Department" And "Sales Department" To Be Added In A Group The Logic Has To Looks Like:</maml:para>
          <maml:para>"(|(department=Finance*)(department=Sales*))(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)"</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
          <maml:para>To Save You Time Researching In Internet About The Correct Syntax For Reference LDAP extensibleMatch Rules OID's When They Are Needed, You Can Use:</maml:para>
          <maml:para>- :Band: When You Need LDAP_MATCHING_RULE_BIT_AND (:1.2.840.113556.1.4.803:)</maml:para>
          <maml:para>- :Bor: When You Need LDAP_MATCHING_RULE_BIT_OR (:1.2.840.113556.1.4.804:)</maml:para>
          <maml:para>- :Expand: When You Need LDAP_MATCHING_RULE_TRANSITIVE_EVAL (:1.2.840.113556.1.4.1941:)</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: RemoveLogic -->
      <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named">
        <maml:name>RemoveLogic</maml:name>
        <maml:description>
          <maml:para>Specifies The Logic For Removing Members From The AD Managed Group.</maml:para>
          <maml:para>The Logic Is Active Directory Attributes Based And Must Comply With The Lightweight Directory Access Protocol (LDAP) Query Language.</maml:para>
          <maml:para>For Best Results I Would Recommend Usage Of Attributes Which Values Are Automatically Maintained, For Example With A Synchronization From An HR Tool.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
          <maml:para>The Provided Value Will Be Used On The Group Members Removing As Follows:</maml:para>
          <maml:para>"(&amp;[RemoveLdapQuery](memberOf=[ADManagedGroupDn]))"</maml:para>
          <maml:para>During The Parameter Validation The CmdLet Will Actually Execute The Following LDAP Query:</maml:para>
          <maml:para>"(&amp;(objectCategory=person)(objectClass=user)[RemoveLdapQuery])"</maml:para>
          <maml:para></maml:para>
          <maml:para>Unlike The AddLogic Here You Most Likely Will Need To Use OR Logic Only. Therefore You Need To Specify The Logic As Follows:</maml:para>
          <maml:para>"(|(!(Attribute1=Value1))(!(Attribute2=Value2)))"</maml:para>
          <maml:para></maml:para>
          <maml:para>For Example When You Need To Remove Users From A Group:</maml:para>
          <maml:para>- When They Are No Longer In "Finance Department" Or "Sales Department".</maml:para>
          <maml:para>- When Their Accounts Get Disabled.</maml:para>
          <maml:para>- When Their Mailboxes Are Disabled.</maml:para>
          <maml:para>"(|(!(|(department=Finance*)(department=Sales*)))(userAccountControl:1.2.840.113556.1.4.803:=2)(!(mail=*)))"</maml:para>
          <maml:para>For RemoveLogic It Just Does Not Make Sense To Use AND Logic. At The End We Need To Remove The Members When One Of The Conditions Occur. It Is Not Likely All Of The Conditions To Occur Simultaneously To Remove A Member.</maml:para>
          <maml:para>NOTE: Unlike The AddLogic The RemoveLogic Actually Does Not Add The Conditions The Removed Object To Be A User Account. Which Means That "SnsPsAdGroupMembers" PSModule Actually Does Remove Group And Contact Member Objects. When You Prepare Your RemoveLogic Please Pay Attention That The Different AD Objects Have Different Sets Of Attributes. For Example If You Have Condition (!(userPrincipalName=*)) This Would Automatically Remove All The Nested Groups And Contacts, Because They Have No UPN Attribute.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
          <maml:para>To Save You Time Researching In Internet About The Correct Syntax For Reference LDAP extensibleMatch Rules OID's When They Are Needed, You Can Use:</maml:para>
          <maml:para>- :Band: When You Need LDAP_MATCHING_RULE_BIT_AND (:1.2.840.113556.1.4.803:)</maml:para>
          <maml:para>- :Bor: When You Need LDAP_MATCHING_RULE_BIT_OR (:1.2.840.113556.1.4.804:)</maml:para>
          <maml:para>- :Expand: When You Need LDAP_MATCHING_RULE_TRANSITIVE_EVAL (:1.2.840.113556.1.4.1941:)</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: Position -->
      <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named" aliases="OrderPosition">
        <maml:name>Position</maml:name>
        <maml:description>
          <maml:para>Specifies The Position For The New AD Managed Group.</maml:para>
          <maml:para>If Omitted The CmdLet Will Assign The Next Value After The Highest Existing Position In The Configuration, Placing The Newly Created Entry In The End Of The Processing Queue.</maml:para>
          <maml:para>"Invoke-SnsAdGroupMembersManage" CmdLet Process The AD Managed Groups In Ascending Order (In Sequence) Based On The AD Managed Group Position. Whenever There Are Dependencies Between The Groups, The Prerequisite Group Have To Be Processed Before The Dependent Group (Must Have Lesser Position). Otherwise The Dependent Group Will Use As Input Outdated Information.</maml:para>
          <maml:para>This Is Not Critical Though On The Next Run The Dependent Groups Will Have The Proper Input Because The Prerequisite Group Will Be Updated (On The Current Run). Wrong Sequence Just Slows Down The Group Members Management.</maml:para>
        </maml:description>
        <command:parameterValue required="true">int</command:parameterValue>
        <dev:type>
          <maml:name>System.Int32</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>-1</dev:defaultValue>
      </command:parameter>
      <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named" aliases="OrderPosition">
        <maml:name>OrderPosition</maml:name>
        <maml:description>
          <maml:para>Specifies The Position For The New AD Managed Group.</maml:para>
          <maml:para>If Omitted The CmdLet Will Assign The Next Value After The Highest Existing Position In The Configuration, Placing The Newly Created Entry In The End Of The Processing Queue.</maml:para>
          <maml:para>"Invoke-SnsAdGroupMembersManage" CmdLet Process The AD Managed Groups In Ascending Order (In Sequence) Based On The AD Managed Group Position. Whenever There Are Dependencies Between The Groups, The Prerequisite Group Have To Be Processed Before The Dependent Group (Must Have Lesser Position). Otherwise The Dependent Group Will Use As Input Outdated Information.</maml:para>
          <maml:para>This Is Not Critical Though On The Next Run The Dependent Groups Will Have The Proper Input Because The Prerequisite Group Will Be Updated (On The Current Run). Wrong Sequence Just Slows Down The Group Members Management.</maml:para>
          <maml:para>This is an alias of the Position parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">int</command:parameterValue>
        <dev:type>
          <maml:name>System.Int32</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>-1</dev:defaultValue>
      </command:parameter>
      <!-- Parameter: Disabled -->
      <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named">
        <maml:name>Disabled</maml:name>
        <maml:description>
          <maml:para>Specifies To Disable The New AD Managed Group Configuration Entry.</maml:para>
          <maml:para>Disabled AD Managed Groups Are Not Processed By "Invoke-SnsAdGroupMembersManage".</maml:para>
        </maml:description>
        <command:parameterValue required="true">SwitchParameter</command:parameterValue>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
      <!-- Parameter: Inclusion -->
      <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named" aliases="ExplicitInclusion">
        <maml:name>Inclusion</maml:name>
        <maml:description>
          <maml:para>Specifies An AD Object To Be Set In The List Of The Specified Managed Group Explicit Inclusions.</maml:para>
          <maml:para>Explicit Inclusions Are Used When We Need To Add An AD Object Which Do Not Match The AddLogic As Group Member.</maml:para>
          <maml:para>Explicit Inclusion Objects External For The AD Domain Are Not Allowed.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Inclusions Will Be Added To The Specified Group.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Have Functionality Different Than The Recommendations And The Best Practices. The Parameter Accepts Only Values Of Types String Or String Array. Normally For Management Of The Explicit Inclusions Have To Be Used The CmdLets With Noun "SnsAdManagedGroupInclusion", Their Parameters Behave According The Best Practices And The MS Recommendations For CmdLet Parameters. I've Included This Parameter Here To Simplify The AD Managed Group Configuration Creation Using A .CSV File Or Excel File Converted To .CSV File. All The Objects Created With "Import-Csv" CmdLet Have Properties Of Type String. Type Of String Array By Default Is Not Available, Without Additional Processing Of The CmdLet Output Objects. From That Perspective This Parameter Can Accept Single String Value And Splits It To String Array On Semicolon (;) And Comma (,) Characters, Assuming That There Will Be No AD Objects Containing Those Characters In The Attributes Used As Identity. To Avoid Issues With The Input Objects Created By "Import-Csv" CmdLet Please Avoid Using Those Characters As .CSV Delimiter And Make Sure The Quotation Marks (") In The .CSV File Are In Their Proper Place.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string[]</command:parameterValue>
        <dev:type>
          <maml:name>System.String[]</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named" aliases="ExplicitInclusion">
        <maml:name>ExplicitInclusion</maml:name>
        <maml:description>
          <maml:para>Specifies An AD Object To Be Set In The List Of The Specified Managed Group Explicit Inclusions.</maml:para>
          <maml:para>Explicit Inclusions Are Used When We Need To Add An AD Object Which Do Not Match The AddLogic As Group Member.</maml:para>
          <maml:para>Explicit Inclusion Objects External For The AD Domain Are Not Allowed.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Inclusions Will Be Added To The Specified Group.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Have Functionality Different Than The Recommendations And The Best Practices. The Parameter Accepts Only Values Of Types String Or String Array. Normally For Management Of The Explicit Inclusions Have To Be Used The CmdLets With Noun "SnsAdManagedGroupInclusion", Their Parameters Behave According The Best Practices And The MS Recommendations For CmdLet Parameters. I've Included This Parameter Here To Simplify The AD Managed Group Configuration Creation Using A .CSV File Or Excel File Converted To .CSV File. All The Objects Created With "Import-Csv" CmdLet Have Properties Of Type String. Type Of String Array By Default Is Not Available, Without Additional Processing Of The CmdLet Output Objects. From That Perspective This Parameter Can Accept Single String Value And Splits It To String Array On Semicolon (;) And Comma (,) Characters, Assuming That There Will Be No AD Objects Containing Those Characters In The Attributes Used As Identity. To Avoid Issues With The Input Objects Created By "Import-Csv" CmdLet Please Avoid Using Those Characters As .CSV Delimiter And Make Sure The Quotation Marks (") In The .CSV File Are In Their Proper Place.</maml:para>
          <maml:para>This is an alias of the Inclusion parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string[]</command:parameterValue>
        <dev:type>
          <maml:name>System.String[]</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <!-- Parameter: Exclusion -->
      <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named" aliases="ExplicitExclusion">
        <maml:name>Exclusion</maml:name>
        <maml:description>
          <maml:para>Specifies An AD Object To Be Set In The List Of The Specified Managed Group Explicit Exclusions.</maml:para>
          <maml:para>Explicit Exclusions Are Used When We Need To Not Add As Group Member An AD Object Which Does Match The AddLogic.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Exclusions Will Be Added To The Specified Group.</maml:para>
          <maml:para>The Parameter Have Functionality Different Than The Recommendations And The Best Practices. The Parameter Accepts Only Values Of Types String Or String Array. Normally For Management Of The Explicit Exclusions Have To Be Used The CmdLets With Noun "SnsAdManagedGroupExclusion", Their Parameters Behave According The Best Practices And The MS Recommendations For CmdLet Parameters. I've Included This Parameter Here To Simplify The AD Managed Group Configuration Creation Using A .CSV File Or Excel File Converted To .CSV File. All The Objects Created With "Import-Csv" CmdLet Have Properties Of Type String. Type Of String Array By Default Is Not Available, Without Additional Processing Of The CmdLet Output Objects. From That Perspective This Parameter Can Accept Single String Value And Splits It To String Array On Semicolon (;) And Comma (,) Characters, Assuming That There Will Be No AD Objects Containing Those Characters In The Attributes Used As Identity. To Avoid Issues With The Input Objects Created By "Import-Csv" CmdLet Please Avoid Using Those Characters As .CSV Delimiter And Make Sure The Quotation Marks (") In The .CSV File Are In Their Proper Place.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string[]</command:parameterValue>
        <dev:type>
          <maml:name>System.String[]</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named" aliases="ExplicitExclusion">
        <maml:name>ExplicitExclusion</maml:name>
        <maml:description>
          <maml:para>Specifies An AD Object To Be Set In The List Of The Specified Managed Group Explicit Exclusions.</maml:para>
          <maml:para>Explicit Exclusions Are Used When We Need To Not Add As Group Member An AD Object Which Does Match The AddLogic.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Exclusions Will Be Added To The Specified Group.</maml:para>
          <maml:para>The Parameter Have Functionality Different Than The Recommendations And The Best Practices. The Parameter Accepts Only Values Of Types String Or String Array. Normally For Management Of The Explicit Exclusions Have To Be Used The CmdLets With Noun "SnsAdManagedGroupExclusion", Their Parameters Behave According The Best Practices And The MS Recommendations For CmdLet Parameters. I've Included This Parameter Here To Simplify The AD Managed Group Configuration Creation Using A .CSV File Or Excel File Converted To .CSV File. All The Objects Created With "Import-Csv" CmdLet Have Properties Of Type String. Type Of String Array By Default Is Not Available, Without Additional Processing Of The CmdLet Output Objects. From That Perspective This Parameter Can Accept Single String Value And Splits It To String Array On Semicolon (;) And Comma (,) Characters, Assuming That There Will Be No AD Objects Containing Those Characters In The Attributes Used As Identity. To Avoid Issues With The Input Objects Created By "Import-Csv" CmdLet Please Avoid Using Those Characters As .CSV Delimiter And Make Sure The Quotation Marks (") In The .CSV File Are In Their Proper Place.</maml:para>
          <maml:para>This is an alias of the Exclusion parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string[]</command:parameterValue>
        <dev:type>
          <maml:name>System.String[]</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <!-- Parameter: Contact -->
      <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named" aliases="NotificationContact,Email,Mail">
        <maml:name>Contact</maml:name>
        <maml:description>
          <maml:para>Specifies Recipients For The Group Related Audit Reports.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Can Be Used For External Recipients. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Contacts Will Be Added To The Specified Group.</maml:para>
          <maml:para>The Parameter Have Functionality Different Than The Recommendations And The Best Practices. The Parameter Accepts Only Values Of Types String Or String Array. Normally For Management Of The Notification Contacts Have To Be Used The CmdLets With Noun "SnsAdManagedGroupContact", Their Parameters Behave According The Best Practices And The MS Recommendations For CmdLet Parameters. I've Included This Parameter Here To Simplify The AD Managed Group Configuration Creation Using A .CSV File Or Excel File Converted To .CSV File. All The Objects Created With "Import-Csv" CmdLet Have Properties Of Type String. Type Of String Array By Default Is Not Available, Without Additional Processing Of The CmdLet Output Objects. From That Perspective This Parameter Can Accept Single String Value And Splits It To String Array On Semicolon (;) And Comma (,) Characters, Assuming That There Will Be No AD Objects Containing Those Characters In The Attributes Used As Identity. To Avoid Issues With The Input Objects Created By "Import-Csv" CmdLet Please Avoid Using Those Characters As .CSV Delimiter And Make Sure The Quotation Marks (") In The .CSV File Are In Their Proper Place.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string[]</command:parameterValue>
        <dev:type>
          <maml:name>System.String[]</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named" aliases="NotificationContact,Email,Mail">
        <maml:name>NotificationContact</maml:name>
        <maml:description>
          <maml:para>Specifies Recipients For The Group Related Audit Reports.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Can Be Used For External Recipients. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Contacts Will Be Added To The Specified Group.</maml:para>
          <maml:para>The Parameter Have Functionality Different Than The Recommendations And The Best Practices. The Parameter Accepts Only Values Of Types String Or String Array. Normally For Management Of The Notification Contacts Have To Be Used The CmdLets With Noun "SnsAdManagedGroupContact", Their Parameters Behave According The Best Practices And The MS Recommendations For CmdLet Parameters. I've Included This Parameter Here To Simplify The AD Managed Group Configuration Creation Using A .CSV File Or Excel File Converted To .CSV File. All The Objects Created With "Import-Csv" CmdLet Have Properties Of Type String. Type Of String Array By Default Is Not Available, Without Additional Processing Of The CmdLet Output Objects. From That Perspective This Parameter Can Accept Single String Value And Splits It To String Array On Semicolon (;) And Comma (,) Characters, Assuming That There Will Be No AD Objects Containing Those Characters In The Attributes Used As Identity. To Avoid Issues With The Input Objects Created By "Import-Csv" CmdLet Please Avoid Using Those Characters As .CSV Delimiter And Make Sure The Quotation Marks (") In The .CSV File Are In Their Proper Place.</maml:para>
          <maml:para>This is an alias of the Contact parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string[]</command:parameterValue>
        <dev:type>
          <maml:name>System.String[]</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named" aliases="NotificationContact,Email,Mail">
        <maml:name>Email</maml:name>
        <maml:description>
          <maml:para>Specifies Recipients For The Group Related Audit Reports.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Can Be Used For External Recipients. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Contacts Will Be Added To The Specified Group.</maml:para>
          <maml:para>The Parameter Have Functionality Different Than The Recommendations And The Best Practices. The Parameter Accepts Only Values Of Types String Or String Array. Normally For Management Of The Notification Contacts Have To Be Used The CmdLets With Noun "SnsAdManagedGroupContact", Their Parameters Behave According The Best Practices And The MS Recommendations For CmdLet Parameters. I've Included This Parameter Here To Simplify The AD Managed Group Configuration Creation Using A .CSV File Or Excel File Converted To .CSV File. All The Objects Created With "Import-Csv" CmdLet Have Properties Of Type String. Type Of String Array By Default Is Not Available, Without Additional Processing Of The CmdLet Output Objects. From That Perspective This Parameter Can Accept Single String Value And Splits It To String Array On Semicolon (;) And Comma (,) Characters, Assuming That There Will Be No AD Objects Containing Those Characters In The Attributes Used As Identity. To Avoid Issues With The Input Objects Created By "Import-Csv" CmdLet Please Avoid Using Those Characters As .CSV Delimiter And Make Sure The Quotation Marks (") In The .CSV File Are In Their Proper Place.</maml:para>
          <maml:para>This is an alias of the Contact parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string[]</command:parameterValue>
        <dev:type>
          <maml:name>System.String[]</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="false" globbing="false" pipelineInput="true (ByPropertyName)" position="named" aliases="NotificationContact,Email,Mail">
        <maml:name>Mail</maml:name>
        <maml:description>
          <maml:para>Specifies Recipients For The Group Related Audit Reports.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Can Be Used For External Recipients. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Contacts Will Be Added To The Specified Group.</maml:para>
          <maml:para>The Parameter Have Functionality Different Than The Recommendations And The Best Practices. The Parameter Accepts Only Values Of Types String Or String Array. Normally For Management Of The Notification Contacts Have To Be Used The CmdLets With Noun "SnsAdManagedGroupContact", Their Parameters Behave According The Best Practices And The MS Recommendations For CmdLet Parameters. I've Included This Parameter Here To Simplify The AD Managed Group Configuration Creation Using A .CSV File Or Excel File Converted To .CSV File. All The Objects Created With "Import-Csv" CmdLet Have Properties Of Type String. Type Of String Array By Default Is Not Available, Without Additional Processing Of The CmdLet Output Objects. From That Perspective This Parameter Can Accept Single String Value And Splits It To String Array On Semicolon (;) And Comma (,) Characters, Assuming That There Will Be No AD Objects Containing Those Characters In The Attributes Used As Identity. To Avoid Issues With The Input Objects Created By "Import-Csv" CmdLet Please Avoid Using Those Characters As .CSV Delimiter And Make Sure The Quotation Marks (") In The .CSV File Are In Their Proper Place.</maml:para>
          <maml:para>This is an alias of the Contact parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string[]</command:parameterValue>
        <dev:type>
          <maml:name>System.String[]</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <!-- Parameter: DomainController -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>DomainController</maml:name>
        <maml:description>
          <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
          <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
          <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
          <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
          <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: Force -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>Force</maml:name>
        <maml:description>
          <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
        </maml:description>
        <command:parameterValue required="true">SwitchParameter</command:parameterValue>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
    </command:parameters>
    <command:inputTypes>
      <command:inputType>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <maml:description>
          <maml:para>Specifies A Not Managed Active Directory Group.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- distinguishedName. Must Be Existing Group In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- displayName. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Group In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Group In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Group In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
        </maml:description>
      </command:inputType>
      <command:inputType>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <maml:description>
          <maml:para>Specifies The Logic For Adding Members Of The AD Managed Group.</maml:para>
          <maml:para>The Logic Is Active Directory Attributes Based And Must Comply With The Lightweight Directory Access Protocol (LDAP) Query Language.</maml:para>
          <maml:para>For Best Results I Would Recommend Usage Of Attributes Which Values Are Automatically Maintained, For Example With A Synchronization From An HR Tool.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
          <maml:para>The Provided Value Will Be Used On The Group Members Adding As Follows:</maml:para>
          <maml:para>"(&amp;(objectCategory=person)(objectClass=user)(!(memberOf=[ADManagedGroupDn]))[AddLogic])"</maml:para>
          <maml:para>During The Parameter Validation The CmdLet Will Actually Execute The Following LDAP Query:</maml:para>
          <maml:para>"(&amp;(objectCategory=person)(objectClass=user)[AddLogic])"</maml:para>
          <maml:para>Therefore The Value Specified To The Parameter Must Have The Following Syntax "([Attribute1]=[Value1])"</maml:para>
          <maml:para></maml:para>
          <maml:para>Whenever You Need To Specify Multiple Conditions And The Added Member Must Comply With All Of Them (AND Logic) You Need Not To Specify AND. The Logic Must Looks Like "([Attribute1]=[Value1])([Attribute2]=[Value2])".</maml:para>
          <maml:para>For Example When You Need All Enabled Users With Mailboxes From "Finance Department" To Be Added In A Group The Logic Has To Looks Like:</maml:para>
          <maml:para>"(department=Finance Department)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)"</maml:para>
          <maml:para></maml:para>
          <maml:para>Whenever You Need To Specify Multiple Conditions With OR Logic. You Need To Specify That. The Logic Must Looks Like "(|([Attribute1]=[Value1])([Attribute2]=[Value2]))".</maml:para>
          <maml:para>For Example When You Need All Enabled Users With Mailboxes From "Finance Department" And "Sales Department" To Be Added In A Group The Logic Has To Looks Like:</maml:para>
          <maml:para>"(|(department=Finance*)(department=Sales*))(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)"</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
          <maml:para>To Save You Time Researching In Internet About The Correct Syntax For Reference LDAP extensibleMatch Rules OID's When They Are Needed, You Can Use:</maml:para>
          <maml:para>- :Band: When You Need LDAP_MATCHING_RULE_BIT_AND (:1.2.840.113556.1.4.803:)</maml:para>
          <maml:para>- :Bor: When You Need LDAP_MATCHING_RULE_BIT_OR (:1.2.840.113556.1.4.804:)</maml:para>
          <maml:para>- :Expand: When You Need LDAP_MATCHING_RULE_TRANSITIVE_EVAL (:1.2.840.113556.1.4.1941:)</maml:para>
        </maml:description>
      </command:inputType>
      <command:inputType>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <maml:description>
          <maml:para>Specifies The Logic For Removing Members From The AD Managed Group.</maml:para>
          <maml:para>The Logic Is Active Directory Attributes Based And Must Comply With The Lightweight Directory Access Protocol (LDAP) Query Language.</maml:para>
          <maml:para>For Best Results I Would Recommend Usage Of Attributes Which Values Are Automatically Maintained, For Example With A Synchronization From An HR Tool.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
          <maml:para>The Provided Value Will Be Used On The Group Members Removing As Follows:</maml:para>
          <maml:para>"(&amp;[RemoveLdapQuery](memberOf=[ADManagedGroupDn]))"</maml:para>
          <maml:para>During The Parameter Validation The CmdLet Will Actually Execute The Following LDAP Query:</maml:para>
          <maml:para>"(&amp;(objectCategory=person)(objectClass=user)[RemoveLdapQuery])"</maml:para>
          <maml:para></maml:para>
          <maml:para>Unlike The AddLogic Here You Most Likely Will Need To Use OR Logic Only. Therefore You Need To Specify The Logic As Follows:</maml:para>
          <maml:para>"(|(!(Attribute1=Value1))(!(Attribute2=Value2)))"</maml:para>
          <maml:para></maml:para>
          <maml:para>For Example When You Need To Remove Users From A Group:</maml:para>
          <maml:para>- When They Are No Longer In "Finance Department" Or "Sales Department".</maml:para>
          <maml:para>- When Their Accounts Get Disabled.</maml:para>
          <maml:para>- When Their Mailboxes Are Disabled.</maml:para>
          <maml:para>"(|(!(|(department=Finance*)(department=Sales*)))(userAccountControl:1.2.840.113556.1.4.803:=2)(!(mail=*)))"</maml:para>
          <maml:para>For RemoveLogic It Just Does Not Make Sense To Use AND Logic. At The End We Need To Remove The Members When One Of The Conditions Occur. It Is Not Likely All Of The Conditions To Occur Simultaneously To Remove A Member.</maml:para>
          <maml:para>NOTE: Unlike The AddLogic The RemoveLogic Actually Does Not Add The Conditions The Removed Object To Be A User Account. Which Means That "SnsPsAdGroupMembers" PSModule Actually Does Remove Group And Contact Member Objects. When You Prepare Your RemoveLogic Please Pay Attention That The Different AD Objects Have Different Sets Of Attributes. For Example If You Have Condition (!(userPrincipalName=*)) This Would Automatically Remove All The Nested Groups And Contacts, Because They Have No UPN Attribute.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
          <maml:para>To Save You Time Researching In Internet About The Correct Syntax For Reference LDAP extensibleMatch Rules OID's When They Are Needed, You Can Use:</maml:para>
          <maml:para>- :Band: When You Need LDAP_MATCHING_RULE_BIT_AND (:1.2.840.113556.1.4.803:)</maml:para>
          <maml:para>- :Bor: When You Need LDAP_MATCHING_RULE_BIT_OR (:1.2.840.113556.1.4.804:)</maml:para>
          <maml:para>- :Expand: When You Need LDAP_MATCHING_RULE_TRANSITIVE_EVAL (:1.2.840.113556.1.4.1941:)</maml:para>
        </maml:description>
      </command:inputType>
      <command:inputType>
        <dev:type>
          <maml:name>System.Int32</maml:name>
          <maml:uri />
        </dev:type>
        <maml:description>
          <maml:para>Specifies The Position For The New AD Managed Group.</maml:para>
          <maml:para>If Omitted The CmdLet Will Assign The Next Value After The Highest Existing Position In The Configuration, Placing The Newly Created Entry In The End Of The Processing Queue.</maml:para>
          <maml:para>"Invoke-SnsAdGroupMembersManage" CmdLet Process The AD Managed Groups In Ascending Order (In Sequence) Based On The AD Managed Group Position. Whenever There Are Dependencies Between The Groups, The Prerequisite Group Have To Be Processed Before The Dependent Group (Must Have Lesser Position). Otherwise The Dependent Group Will Use As Input Outdated Information.</maml:para>
          <maml:para>This Is Not Critical Though On The Next Run The Dependent Groups Will Have The Proper Input Because The Prerequisite Group Will Be Updated (On The Current Run). Wrong Sequence Just Slows Down The Group Members Management.</maml:para>
        </maml:description>
      </command:inputType>
      <command:inputType>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <maml:description>
          <maml:para>Specifies To Disable The New AD Managed Group Configuration Entry.</maml:para>
          <maml:para>Disabled AD Managed Groups Are Not Processed By "Invoke-SnsAdGroupMembersManage".</maml:para>
        </maml:description>
      </command:inputType>
      <command:inputType>
        <dev:type>
          <maml:name>System.String[]</maml:name>
          <maml:uri />
        </dev:type>
        <maml:description>
          <maml:para>Specifies An AD Object To Be Set In The List Of The Specified Managed Group Explicit Inclusions.</maml:para>
          <maml:para>Explicit Inclusions Are Used When We Need To Add An AD Object Which Do Not Match The AddLogic As Group Member.</maml:para>
          <maml:para>Explicit Inclusion Objects External For The AD Domain Are Not Allowed.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Inclusions Will Be Added To The Specified Group.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Have Functionality Different Than The Recommendations And The Best Practices. The Parameter Accepts Only Values Of Types String Or String Array. Normally For Management Of The Explicit Inclusions Have To Be Used The CmdLets With Noun "SnsAdManagedGroupInclusion", Their Parameters Behave According The Best Practices And The MS Recommendations For CmdLet Parameters. I've Included This Parameter Here To Simplify The AD Managed Group Configuration Creation Using A .CSV File Or Excel File Converted To .CSV File. All The Objects Created With "Import-Csv" CmdLet Have Properties Of Type String. Type Of String Array By Default Is Not Available, Without Additional Processing Of The CmdLet Output Objects. From That Perspective This Parameter Can Accept Single String Value And Splits It To String Array On Semicolon (;) And Comma (,) Characters, Assuming That There Will Be No AD Objects Containing Those Characters In The Attributes Used As Identity. To Avoid Issues With The Input Objects Created By "Import-Csv" CmdLet Please Avoid Using Those Characters As .CSV Delimiter And Make Sure The Quotation Marks (") In The .CSV File Are In Their Proper Place.</maml:para>
        </maml:description>
      </command:inputType>
      <command:inputType>
        <dev:type>
          <maml:name>System.String[]</maml:name>
          <maml:uri />
        </dev:type>
        <maml:description>
          <maml:para>Specifies An AD Object To Be Set In The List Of The Specified Managed Group Explicit Exclusions.</maml:para>
          <maml:para>Explicit Exclusions Are Used When We Need To Not Add As Group Member An AD Object Which Does Match The AddLogic.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Exclusions Will Be Added To The Specified Group.</maml:para>
          <maml:para>The Parameter Have Functionality Different Than The Recommendations And The Best Practices. The Parameter Accepts Only Values Of Types String Or String Array. Normally For Management Of The Explicit Exclusions Have To Be Used The CmdLets With Noun "SnsAdManagedGroupExclusion", Their Parameters Behave According The Best Practices And The MS Recommendations For CmdLet Parameters. I've Included This Parameter Here To Simplify The AD Managed Group Configuration Creation Using A .CSV File Or Excel File Converted To .CSV File. All The Objects Created With "Import-Csv" CmdLet Have Properties Of Type String. Type Of String Array By Default Is Not Available, Without Additional Processing Of The CmdLet Output Objects. From That Perspective This Parameter Can Accept Single String Value And Splits It To String Array On Semicolon (;) And Comma (,) Characters, Assuming That There Will Be No AD Objects Containing Those Characters In The Attributes Used As Identity. To Avoid Issues With The Input Objects Created By "Import-Csv" CmdLet Please Avoid Using Those Characters As .CSV Delimiter And Make Sure The Quotation Marks (") In The .CSV File Are In Their Proper Place.</maml:para>
        </maml:description>
      </command:inputType>
      <command:inputType>
        <dev:type>
          <maml:name>System.String[]</maml:name>
          <maml:uri />
        </dev:type>
        <maml:description>
          <maml:para>Specifies Recipients For The Group Related Audit Reports.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Can Be Used For External Recipients. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Contacts Will Be Added To The Specified Group.</maml:para>
          <maml:para>The Parameter Have Functionality Different Than The Recommendations And The Best Practices. The Parameter Accepts Only Values Of Types String Or String Array. Normally For Management Of The Notification Contacts Have To Be Used The CmdLets With Noun "SnsAdManagedGroupContact", Their Parameters Behave According The Best Practices And The MS Recommendations For CmdLet Parameters. I've Included This Parameter Here To Simplify The AD Managed Group Configuration Creation Using A .CSV File Or Excel File Converted To .CSV File. All The Objects Created With "Import-Csv" CmdLet Have Properties Of Type String. Type Of String Array By Default Is Not Available, Without Additional Processing Of The CmdLet Output Objects. From That Perspective This Parameter Can Accept Single String Value And Splits It To String Array On Semicolon (;) And Comma (,) Characters, Assuming That There Will Be No AD Objects Containing Those Characters In The Attributes Used As Identity. To Avoid Issues With The Input Objects Created By "Import-Csv" CmdLet Please Avoid Using Those Characters As .CSV Delimiter And Make Sure The Quotation Marks (") In The .CSV File Are In Their Proper Place.</maml:para>
        </maml:description>
      </command:inputType>
    </command:inputTypes>
    <command:returnValues>
      <!-- OutputType: SnsAdManagedGroup -->
      <command:returnValue>
        <dev:type>
          <maml:name>SnsAdGroupMembers.SnsAdManagedGroup</maml:name>
          <maml:uri />
        </dev:type>
      </command:returnValue>
    </command:returnValues>
    <maml:alertSet>
      <maml:title></maml:title>
      <maml:alert>
        <maml:para>AUTHOR: Svetoslav Nedyalkov Savov</maml:para>
        <maml:para>THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK</maml:para>
        <maml:para>OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.</maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
      </maml:alert>
    </maml:alertSet>
    <command:examples>
      <command:example>
        <maml:title>---------- EXAMPLE 1 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = New-SnsAdManagedGroup -Identity "Finance Department DL" `
-AddLogic "(department=Finance Department)(!(userAccountControl:Band:=2))(mail=*)" `
-RemoveLogic "(|(!(department=Finance*))(userAccountControl:Band:=2)(!(mail=*)))" `
-Inclusion "john.smith@contoso.com;jane.smith@contoso.com" -Exclusion "adam.smith@contoso.com" `
-Contact "john.smith@contoso.com", "eve.smith@contoso.com" -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Creates Managed AD Group Configuration Object For "Finance Department DL" Active Directory Group With The Specified "AddLogic" And "RemoveLogic" With The Next Available Position (After The Existing Group Configuration Entries).</maml:para>
          <maml:para>Calls In Background "Set-SnsAdManagedGroupInclusion" CmdLet To Set john.smith@contoso.com And jane.smith@contoso.com As Explicit Inclusions To The Newly Created AD Managed Group Entry. The Entries Are Provided As A Single String Value. The Parameter Split It To String Array On Semicolon (;) Character.</maml:para>
          <maml:para>Calls In Background "Set-SnsAdManagedGroupExclusion" CmdLet To Set adam.smith@contoso.com As Explicit Exclusion To The Newly Created AD Managed Group Entry.</maml:para>
          <maml:para></maml:para>
          <maml:para>Calls In Background "Set-SnsAdManagedGroupContact" CmdLet To Set john.smith@contoso.com And eve.smith@contoso.com As Notification Contacts To The Newly Created AD Managed Group Entry. The Values Are Provided As String Array.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 2 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Import-Csv -Path "C:\GroupsCfg.csv" -Delimiter "|" `
-Encoding "ASCII" | New-SnsAdManagedGroup;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Imports .CSV File "C:\GroupsCfg.csv" During The Import Pipeline (|) Character Is Considered As Delimiter. The Output Objects Are Send Via The PowerShell Pipeline To "New-SnsAdManagedGroup" Which Creates The AD Managed Group Entries As They Are Specified In The .CSV File.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Order "New-SnsAdManagedGroup" To Accept Properly The Objects Sent Via Pipeline, They Must Have Properties Corresponding To The CmdLet Parameters. Therefore The .CSV File Must Have Column Names In The .CSV Header That Correspond To "New-SnsAdManagedGroup" Parameter Names Or Parameter Aliases. Have Multiple CmdLet Parameter Aliases Allows More Flexibility In The .CSV File Column Names.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 3 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = New-SnsAdManagedGroup -Identity "Finance Department DL" `
-AddLogic "(department=Finance Department)(!(userAccountControl:Band:=2))(mail=*)" -Inclusion "Smith, John";</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Throws An Error And The AD Managed Group Entry Is Not Created. The Reason Is Related With The Unusual Behavior Of The Inclusion Parameter. The Display Name Of User John Smith Contains Comma (,). This Leads To Splitting Of The Specified String Value On Comma (,) Character. As A Result The Parameter Validation Can Not Unambiguously Identify The Users Account And Throws Error. In Cases Like That First Create The Configuration Entry Without The Inclusion, Exclusion And Notification Contact Entries And Then Use The Corresponding CmdLets To Add Them. Alternatively You Can Use An AD Attribute Value Which Does Not Contain Comma (,) Or Semicolon (;) Characters. This Exactly Is The Reason Those Parameters To Not Accept distinguishedName Values.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
    </command:examples>
    <maml:relatedLinks>
      <maml:navigationLink>
        <maml:linkText> svesavov / SnsPsAdGroupMembers - </maml:linkText>
        <maml:uri>https://github.com/svesavov/SnsPsAdGroupMembers</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> PowerShell Gallery - </maml:linkText>
        <maml:uri>https://www.powershellgallery.com/packages/SnsPsAdGroupMembers/</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> Svetoslav Savov on LinkedIn - </maml:linkText>
        <maml:uri>https://www.linkedin.com/in/svetoslavsavov</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> SQLite V3 - </maml:linkText>
        <maml:uri>https://sqlite.org/index.html</maml:uri>
      </maml:navigationLink>
    </maml:relatedLinks>
  </command:command>
  <!-- Cmdlet: Remove-SnsAdManagedGroup -->
  <command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
    <command:details>
      <command:name>Remove-SnsAdManagedGroup</command:name>
      <command:verb>Remove</command:verb>
      <command:noun>SnsAdManagedGroup</command:noun>
      <maml:description>
        <maml:para>Deletes Managed Active Directory Group Configuration.</maml:para>
      </maml:description>
    </command:details>
    <maml:description>
      <maml:para>Deletes Managed Active Directory Group Configuration.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Operation Of "SnsPsAdGroupMembers" PSModule Install It With "AllUsers" Scope. The Idea Behind This Module Is To Be Used On A Scheduled Task "As Service" For The Actual Group Members Management, And Interactively By IT Administrators To Create And Modify The Managed Groups Configuration. This Requires The PSModule To Be Available To Multiple User Accounts.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Creation Of "SnsPsAdGroupMembers" PSModule DataBases, The First Load Of The PSModule Must Be In Elevated Mode. In The Normal Operation The PSModule Does Not Require Elevated Mode. More Information About That Is Provided Further In This Document.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"Why Should I Use This PSModule Instead Of Dynamic Groups?":</maml:para>
      <maml:para>- Well First And Foremost Reason Is Related With The Fact That This PowerShell Module Does Allow To Have Different Logic For Adding And Removing Members. This Is Not Achievable With Dynamic Groups.</maml:para>
      <maml:para>- The Company IT Department Might Need To Use A Single Group For Granting Access Rights In On Premises AD, AzureAD And Use It As Distribution List At The Same Time. Although This Can Be Achieved With Dynamic Groups You Have To Maintain At Least Two Of Them, One For On Premises AD And One For AzureAD.</maml:para>
      <maml:para>- There Are Cases Related With Certain AzureAD Functionalities And Synchronizations With Third Party Cloud Solutions Which Do Not Support Nested And Dynamic Groups. Managing Of Groups With Large Number Of Members In Corporate Environment Without Using Of Group Nestling Could Be Quite Tricky And Related With Lot Of Users Frustration And Administrative Effort.</maml:para>
      <maml:para>- The "SnsPsAdGroupMembers" PSModule Prepare Reports About Modifying Group Members And Audit Of Changes In The Group Management Settings. Whenever A Group Is Used For Granting Sensitive Access Rights Or Managing The Members Of A Sensitive Distribution List, The Group Owners Might Want To Receive Those Reports, Often Immediately After The Above-Mentioned Actions Are Taken.</maml:para>
      <maml:para>- The PSModule Can Be Used Only For Adding Or Only For Removing Members. Using Of Both Is Not Mandatory. This Does Allow Implementation Of Process For Adding Members In Sensitive Groups, Like "Domain Admins" For Example, Following Formal Approval Process, But Removing Members Immediately When The Person Who Owns The Account Leave The Company, Or Change The Position. In This Case There Will Be Zero Tolerance For Users "Forgotten" With More Than Needed Access Rights.</maml:para>
      <maml:para>This PSModule Have The Same Disadvantages And Requirements As The Dynamic Groups. Since The Management Logic Is Based On AD Attribute Values, It Requires The Used Ones To Be Up To Date And Consistent. Some Sort Of Synchronization From The Company HR System Would Address This. Such A Synchronization Is Nice To Have But Not A Requirement. Using My Other PSModule's Will Be Relatively Easy Creation Of Own Synchronization Related With Any On Premises HR Application. Most Of The Cloud Based Ones, Already Have Out Of The Box Synchronization Tools. Creation Of New One Would Not Be Feasible, But It Depends On The API's The Tool Provides.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Manages The Membership Of Active Directory Groups In A Single Domain Forest Based On Predefined Logic About Adding And Removing Members. For That Purpose, The PowerShell Module Uses SQLite Configuration DataBase To Keep Information About:</maml:para>
      <maml:para>- The Managed Groups.</maml:para>
      <maml:para>- The Logic For Adding Members Into Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- The Logic For Removing Members From Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- Explicit Group Inclusions. Those Are AD Objects Which Shall Be Added As Group Members, Although They Do Not Meet The Adding Criteria.</maml:para>
      <maml:para>- Explicit Group Exclusions. Those Are AD Objects Which Shall Not Be Added As Group Members, Although They Do Meet The Adding Criteria.</maml:para>
      <maml:para>- Notification Contacts Who Shall Receive Reports About The Actions And Audit Events Related With Their Own Groups.</maml:para>
      <maml:para>- The PSModule Configuration.</maml:para>
      <maml:para>- Managed Groups Configuration Changes Tracking.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Uses Another SQLite DataBase To Store All The Events Related With The CmdLets Operation And Events Related With Actions Taken On The Managed Groups.</maml:para>
      <maml:para></maml:para>
      <maml:para>To Increase The Confidence In The Automation Among The Group Owners, "SnsPsAdGroupMembers" PSModule Produces Reports Intended To Be Provided To Those Owners, Whenever The PSModule Adds And / Or Removes Members, Whenever It Detects Changes In The Groups Configuration That Might Affect The Group Members, Such Like Changes In The Add Logic, Remove Logic, Explicit Inclusions, Explicit Exclusions And Notification Contacts.</maml:para>
      <maml:para>In Case Of Changes In The Notification Contacts, Both The Old And New Contacts Are Included In The Report Recipients List. The Reports Are Prepared Only When Actual Changes Are Made Or Detected Whenever The Actual Group Management Occur. For That Purpose, The PSModule Uses An SQLite Statistics DataBase To Store Information About:</maml:para>
      <maml:para>- Events Related With Automatic Adding Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Automatic Removing Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Changes In Managed Groups Configuration That Might Affect The Group Membership, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With The Module Operation And Groups Management Intended To Be Provided To The Company IT's. The Internal Events Not Related With Specific Managed Group Are Not Kept In The Statistics DataBase. Therefore The Statistics DataBase Is Not Suitable Source Of Information About Troubleshooting Of Performance, Module Related Issues, And Script Related Issues. However It Is Perfectly Reliable Source Of Troubleshooting Information Related With Troubleshooting Of Incorrect Logic And Any Managed Groups Misconfiguration.</maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Only Prepares Reports And Reverts Them As "SnsReportCollection" Output Object. The Email Relay Options Differ From One Environment To Another, It Is Not Feasible To Maintain Multiple Settings Related With Email Sending In The Configuration DataBase, While Sending Of An Email From PowerShell Is Simple As Running Of A CmdLet. Depending On The Company, Might Be Used Different Languages, Different Wording, Company Branding, Company Stationaries, Company Colors And Company Visual Stylings In The Emails. From That Perspective The PSModule Reverts Reports In Custom Objects And Collections. The User Have To Convert Them To HTML Text And Send Them As Emails, Within The Automation Scripts Which Use "SnsPsAdGroupMembers" Module. The Simplest Way For Doing That Is Using "ConvertTo-Html" And "Send-MailMessage" Native PowerShell CmdLets. Whenever Managed Group Owners Are Not Interested To Receive Any Notifications The Reports For They Own Groups Can Be Disabled Via Leaving Empty The Notification Contacts Setting Of The Group (Or Remove All Notification Contacts For A Managed Group If There Are Already Specified). This Does Not Disable The Logging Of Events Into The Statistics DataBase.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>For DataBase Engine Is Used SQLite. SQLite Is Free Open Source Serverless DataBase, Which Comes With Its Own Advantages And Disadvantages. As Serverless DataBase There Is No Server To Manage The DataBase Requests And Locks. From That Perspective Using A Single SQLite DataBase Either Over Network Or Mapped Drives Or Simultaneously By Multiple Applications / PSSessions Might Lead To Errors In Accessing The DataBase Or DataBase Corruption.</maml:para>
      <maml:para>From That Perspective All The CmdLets Within This Module Have A Feature That Prevents Running Of Those CmdLets In Multiple PowerShell Sessions. All The CmdLets Have Parameter "Force" Which Allows The Usage Of The CmdLets In Multiple PSSessions, Use It At Your Own Risk. The Parameter Is Ignored And Does Not Work When The PSSession Is "As A Service" (In Automation Script Executed With Scheduled Task For Example).</maml:para>
      <maml:para>Both The Configuration And Statistics DataBases Are Located In "C:\ProgramData\SnsAdGroupMembers" By Default. In Order The Folder And DataBase Files To Be Created Properly, The First Run Of This CmdLet To Be Made In Elevated PowerShell Session. Creation Of The DataBase Folder And Setting The Required NTFS Permissions Requires Local Administrator Access Rights. The DataBase Files Can Be Moved / Migrated Into Different Folders, In That Case The Administrator Who Is Doing That Have To Make Sure That The Folder Exists, All The Users That Will Use This PSModule Will Have "Modify" NTFS Permissions Over The Folder And The DataBase Files, Move The DataBase Files Into The New Folder And Properly Provide The Module With The New Folder Absolute (Full) Path.</maml:para>
      <maml:para>Although Using This PSModule On Domain Controllers Is Possible, It Is Against The Best Practices And It Is Not Recommended. All Automations Shall Be Run On Dedicated Virtual Or Physical Machine. From That Perspective It Is Required "Local Admin" Access Rights.</maml:para>
      <maml:para>It Is Not Recommended The DataBase Files To Be Moved, And If That Happen They Shall Be Not Moved On Network Shares Or Mapped Drives. This Will Not Prevent The PSModule To Do Its Job. It Will Introduce Performance Degradation, Possible Interruption In Case Of Network Issues And Eventually Corruption Of The DataBases.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>Never Move DataBases Outside The Default Location When The PSModule Is Installed With Scope "CurrentUser".</maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>"CfgDbFolder" Setting Specifies The Location Of Both Configuration And Statistics DataBases Simultaneously Unless The Statistics DataBase Have Explicitly Specified Location. With Other Words When Modify Configuration DataBase Location And "StatDbFolder" Setting Is Not Used, Both DataBases Have To Be Moved In The New Location.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Contains CmdLets Intended To Be Run Interactively By The User And CmdLets Intended To Be Run Within Automation Scripts On A Schedule As A Service. The CmdLets Intended To Be Used Within Automation Scripts Comply With Additional Requirements Related With Logging, Reporting And Ability To Being Monitored (Using "SnsPsScriptsMonitoring" PSModule For Example). "Invoke-SnsAdGroupMembersManage" Is A CmdLet Intended To Be Used In An Automation Scripts. By Its Nature, This CmdLet Is An Automation Encapsulated Within A CmdLet. The Logs And Events Happening During The CmdLet Run Are Logged In An SQLite DataBase "GroupMembersProvStat.db" Referred Furter As Statistics DataBase. It Could Be Used For Other Reporting Purposes Like Periodical Comprehensive Reports About The Actions Taken By Automation Scripts (This Requires Additional Scripting To Read The DataBase And Prepare The Reports).</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>When Working With Active Directory It Is Important What Identity Attribute Will Be Chosen For Binding To The AD Objects. Although Naturally AD Uses DistinguishedName For Binding And LDAP Queries, It Is Not The Best Possible Identity. The DistinguishedName Is Unique But It Is Not Constant, It Can Be Changed Over The AD Object Life Cycle. An AD Object Can Be Renamed And / Or Moved Into Different Organizational Unit, Or The Organizational Unit Where The Object Is Located Can Be Renamed And / Or Moved. That Will Modify Object's Distinguished Name. In This Case The Active Directory Will Automatically Reflect Those Changes In The Attributes Of The Object And On All Relational Attributes Of The Remaining Objects Which Point To Our Object. For Example "member" Attribute Of All The Groups Where Our AD Object Is Member Of, Or "manager" Attribute Of All Accounts That Our User Is Manager. However AD Will Not Modify Accordingly The PSModule Configuration Stored In An External For The AD DataBase. This Will Lead To Errors And Failures.</maml:para>
      <maml:para>It Is Best Practice The AD Related Applications To Use For Binding Other Identity Attributes Which Do Not Change During The Objects Life Cycle. Those Are "objectGUID" And "objectSid". The Best Practices Gives Preference To The "objectSid" By Various Reasons. Since It Is Possible Groups To Have Member Objects Without "objectSid" (Contact Objects For Example) The "SnsPsAdGroupMembers" PSModule Uses As Identity The "ObjectGUID" Attribute. Thus Way When An Object Is Renamed Or Moved The PSModule Is Not Affected And Continue To Work As Intended.</maml:para>
      <maml:para>The The Well-Known AD Behavior, That When An Object Is Deleted And Then Recreated, All The Access Rights And Group Membership Are Lost, Is Related With The Fact That The Recreated Object Have Different "objectSid". Using The "objectGUID" As Identity Introduces Similar Behavior Of "SnsPsAdGroupMembers". Deletion And Recreation Of An AD Group Object Does Not Automatically Enable It For Automatic Members Management With The Logic Of The Deleted Group.</maml:para>
      <maml:para>The Using "objectGUID" As Identity In The PSModule Configuration Ensures That The PSModule Is Not Affected By Objects Rename Or Objects Move. When A Managed Group, Explicit Inclusion, Explicit Exclusion Is Renamed Or Moved Into Different OU, Their "objectGUID" Remains Intact. And The PSModule Continue To Bind To Those Objects Without Errors. However This Does Introduce Additional Overhead For The CmdLets Intended To Manage The Groups Configuration. When An Object Is Provided To Them They Need To Search For That Object In Active Directory, Enumerate The "objectGUID" Of The Object And Specify The Enumerated Value Into The Configuration DataBase. Since The CmdLets Query AD, That Query Can Be Made Against Multiple Attributes, Which Does Provide Freedom For The User To Use Multitude Of Values When An AD Object Is Provided To A Parameter. Please Refer To Each To The Parameters Sections Of Each CmdLet Help Document.</maml:para>
      <maml:para>When LDAP Queries Are Needed The Things Get More Complicated. The LDAP Queries Work Only With DistinguishedName. When You Need To Query About Reports Of A Person, Or Members Of A Group The AD Expects LDAP Query With DistinguishedName Values. An Example Of Often Use LDAP Query Clause Is:</maml:para>
      <maml:para>"(manager=CN=Jane Smith,CN=Users,DC=contoso,DC=com)"</maml:para>
      <maml:para>If "SnsPsAdGroupMembers" PSModule Keep It As Is Into The Configuration, In Case Of DistinguishedName Change, The Logic Will Revert No Results, Which Might Lead To Removal Of All The Members From The Group. Instead The LDAP Clause Is Stored Like:</maml:para>
      <maml:para>"(manager=00000000-0000-0000-0000-000000000000)"</maml:para>
      <maml:para>This Complicates The PSModule Further, As On The AD Managed Group Configuration Creation / Modification It Have To Evaluate The Specified Parameters, Match Them Using RegEx Pattern About Any Distinguished Names, Bind To The AD Object Using The Matched DistinguishedName, Enumerates The AD Object "objectGUID" And Amend The Matched DistinguishedName With The Enumerated "objectGUID". And Before The Actual AD Managed Group Members Management, It Have To Evaluate The Configuration About "objectGUID" Values Using RegEx Matching, Bind To The AD Object Using The Matched "objectGUID", Enumerate The AD Object DistinguishedName And Amend The "objectGUID" With The Enumerated DistinguishedName. Thus Way Introducing Overhead For The PSModule And For The Domain Controller Which Serves The LDAP Requests.</maml:para>
      <maml:para>To Reduce The Number Of The AD Requests And The Overhead, The PSModule Caches The Attributes Of The Previously Bind To Or Queried About AD Objects, And Consequently Uses The Cache Instead Of Making New AD Requests. The Effectiveness Of The AD Cache Depends On The Similarities In The Configuration Of The Groups.</maml:para>
      <maml:para>The Attributes Modified By The "SnsPsAdGroupMembers" PSModule Like "memberOf" AD Attribute, Are Never Cached. Caching Those Might Lead To False Positive Or Real Errors.</maml:para>
      <maml:para>The Values Of The AD Attributes Without Requirements For Uniqueness Cannot Be Used For Indexing And Searches In The Cache. For Example There Is No Uniqueness Requirement For "cn" Attribute, You Can Have Multiple Objects With The Same "cn" As Long As They Are Located In Different OU's. When A CmdLet Parameter From The PSModule Is Provided With "cn" Value, It Must Make LDAP Search To Enumerate The AD Object, Either To Confirm That The Value Corresponds To An AD Object Or To Throw Error About Multiple Objects. In Case We Have The Specified Value In The Cache It Is Not Certain That There Are No Other Objects With The Same Value In The AD Domain. Whenever We Use AD Attributes With Uniqueness Requirements Like Distinguished Name, For Example Presence Of The Provided Value In The Cache Can Be Safely Assumed As Correct And Unique, In That Case Query Against The AD Domain Is Not Needed. Usage Of Values In Attributes Without Uniqueness Requirements Reduces The Effectiveness Of The AD Cache Feature Further.</maml:para>
      <maml:para>Introducing A Cache In The PSModule Introduces All Generic Disadvantages Related With Caching, Like Cached Outdated Values. The "SnsPsAdGroupMembers" PSModule Keeps The AD Cache In The System Memory. This Does Ensure Maximum Speed For Accessing The Cache, With Negative Impact On The Machine Performance Because Of The Increased Memory Usage. Together With The Feature Which Does Not Allow Usage Of The PSModule In Multiple PSSession (Which Actually Force The Users To Close Their PSSessions Once They Finish Their Job), Ensures Relatively Short Life Span Of The Cached Entries, Thus Way Reducing The Cache Effectiveness But Increasing The Reliability Via Minimizing The Possibility For Issues Related With Outdated Entries.</maml:para>
      <maml:para>Although The Shorter Lifespan Of The Cached Entries Reduces The Possibility For Mistakes, It Does Not Eliminate Them Completely. Mistakes Might Happen Without Corrupted Or Outdated Cached Entry. Let Us Assume We Have A Department Related Group Where Members Are Added Based On Specific Value In The Department AD Attribute And Removed When The Value Is Different. At The Same Time, The Department AD Attribute Is Automatically Synchronized From The Company HR System. In Case Of Department Rebranding The Sync From The HR System Will Modify The Attribute Value Of All Department Members. In That Case All The Department Members Will Be Removed From The Group. This Is Addressed With Introducing Of New Feature Which Prevents Any Members Removal Whenever The Members Enumerated For Removing Are More Than Certain Threshold. The Threshold Is Configurable. The Default Value Is 50%.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" Provides A Feature Intended For Quick Identifying Whether A Group Is Automatically Managed Or Not, Which Is Disabled By Default. It Could Be Very Annoying And Frustrating To Manually Add Or Remove A Member Into A Group And The Automation To Revert The Changes Back Because The Member Does Not Match The Adding Or Match The Removing Criteria For The Automatic Group Members Management. Normally The IT Administrators Would Need To Check In The PS Module Configuration To Verify Whether An AD Group Is Automatically Managed Using The PSModule Before Membership Modification. This Might Lead To Failed Scheduled Tasks Due To Multiple PSSessions With The PSModule Loaded. From That Perspective "SnsPsAdGroupMembers" Stores A Predefined Constant Value In A Predefined AD Attribute Of The AD Managed Groups And Clears The Predefined Constant Value From The Predefined AD Attribute Of The Not Managed Groups. Therefore The Company IT Administrators Just Need To Look At That Attribute Before Manually Add Or Remove Groups Members In An AD Group.</maml:para>
      <maml:para>To Enable This Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet, To Specify An AD Attribute And A Constant Value Which Shall Be Set On The AD Managed Groups. To Disable That Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet To Clear Either The Value Or The AD Attribute Used By This Feature Or Both. When Enabled On A Scheduled Job After Actual Group Management "Invoke-SnsAdGroupMembersManage" Sets The Predefined Constant Value Into The Predefined AD Attribute Of All Enabled AD Managed Groups And Clears The Value From All Not Managed AD Groups. Therefore Once The Feature Is Disabled The User Have To Manually Clear The Value From The AD Attribute Of All The Groups In Case The Feature Was Ever Used. Changing The Attribute Will Not Clear The Value From The Old Attribute.</maml:para>
      <maml:para>NOTE: This Feature Considers As Managed Only The Groups That Are Enabled In The Groups Configuration. Disabling A Group From Automatic Members Management, Even Temporary Will Clear The AD Attribute Used By This Feature, Indicating To The Corporate IT Administrators, That The Group Membership Can Be Managed Manually.</maml:para>
      <maml:para>NOTE: This Feature Can Use Only AD Attributes With Type Of Single Valued String.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>Remove-SnsAdManagedGroup Is Intended To Be Used Interactively By A User To Delete A Managed AD Group Configuration From The Configuration DataBase.</maml:para>
      <maml:para>NOTE: Please Make Sure That The PowerShell Is Closed, When You Finish With The Work On The Managed AD Groups Configuration. Otherwise Either The Other Users Or Any Automated Task Will Be Prevented From Work With The PSModule.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In Parameters Validation The CmdLet Query The Configuration DataBase And Enumerates The Provided By The User Objects. In Case The Specified Objects Does Not Exists The CmdLet Throws Error. The Parameters Which Accept Wildcard Usage Requires To Identify Unambiguously The Specified Object. Therefore If A Specified Wildcard Pattern Revert More Than One Object, The CmdLet Will Throw Error. Use The Wildcards Only To Spare Typing When You Are Completely Sure It Will Revert Single Object.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "BeginProcessing" Method "Remove-SnsAdManagedGroup" CmdLet Initializes The PSModule Configuration. Verifies The Existence, The Schema And The Integrity Of The Configuration DataBase. Verifies About Other PowerShell Processes Using "SnsPsAdGroupMembers" PSModule.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "ProcessRecord" Method "Remove-SnsAdManagedGroup" CmdLet Enumerates The Configuration Entries For Each Group Coming From The Pipeline Or Specified With "Identity" Parameter And Deletes Them. In Case The Deletion Is Successful The CmdLet Does Not Revert Output. Whenever The Deletion Does Not Happen Either Because The User Did Not Confirmed The Deletion Or When The CmdLet Is Run With WhatIf Parameter Or Any Failure, AD Managed Group Object Is Send To The Pipeline.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The CmdLet Reverts SnsAdManagedGroup Objects With The Following Properties And Methods:</maml:para>
      <maml:para>- "Position" Property Of Type Integer. Represents The Group Position In The Collection For Members Management.</maml:para>
      <maml:para>- "Identity" Property Of Type Guid. Represents The Managed Group AD "objectGUID".</maml:para>
      <maml:para>- "Name" Property Of Type String. Contains The Value Of The Managed Group "cn" Attribute.</maml:para>
      <maml:para>- "AddLogic" Property Of Type String. Contains The Logic For Adding Members Into The Managed Group.</maml:para>
      <maml:para>- "RemoveLogic" Property Of Type String. Contains The Logic For Removing Members From The Managed Group.</maml:para>
      <maml:para>- "Inclusions" Property Of Type SnsAdManagedGroupInclusion Array. Contains An Array With The Group's Explicit Inclusions. Each SnsAdManagedGroupInclusion Object Contains: "Identity" Property Of Type Guid. "Name" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Exclusions" Property Of Type SnsAdManagedGroupExclusion Array. Contains An Array With The Group's Explicit Exclusions. Each SnsAdManagedGroupExclusion Object Contains: "Identity" Property Of Type Guid. "Name" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Notify" Property Of Type SnsAdManagedGroupContact Array. Contains An Array With The Group's Notification Contacts. Each SnsAdManagedGroupContact Object Contains: "Email" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Enabled" Property Of Type Boolean. Represents Whether The Managed Group Entry Is Active Or Not.</maml:para>
      <maml:para>- "GetSnsRawAddLogic" Method Intended To Revert The Not Normalized Add Logic As It Is Set In The Group Configuration.</maml:para>
      <maml:para>- "GetSnsRawRemoveLogic" Method Intended To Revert The Not Normalized Remove Logic As It Is Set In The Group Configuration.</maml:para>
    </maml:description>
    <command:syntax>
      <!-- Parameter set: __AllParameterSets -->
      <command:syntaxItem>
        <maml:name>Remove-SnsAdManagedGroup</maml:name>
        <!-- Parameter: Identity -->
        <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
          <maml:name>Identity</maml:name>
          <maml:description>
            <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
            <maml:para>The Parameter Accepts The Following Values:</maml:para>
            <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
            <maml:para>- objectGUID</maml:para>
            <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
            <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
            <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
            <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          </maml:description>
          <command:parameterValue required="true">object</command:parameterValue>
          <dev:type>
            <maml:name>System.Object</maml:name>
            <maml:uri />
          </dev:type>
        </command:parameter>
        <!-- Parameter: DomainController -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>DomainController</maml:name>
          <maml:description>
            <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
            <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
            <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
            <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
            <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
        <!-- Parameter: Force -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>Force</maml:name>
          <maml:description>
            <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
    <command:parameters>
      <!-- Parameter: Identity -->
      <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
        <maml:name>Identity</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
        <maml:name>Group</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>This is an alias of the Identity parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
        <maml:name>ManagedGroup</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>This is an alias of the Identity parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <!-- Parameter: DomainController -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>DomainController</maml:name>
        <maml:description>
          <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
          <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
          <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
          <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
          <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: Force -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>Force</maml:name>
        <maml:description>
          <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
        </maml:description>
        <command:parameterValue required="true">SwitchParameter</command:parameterValue>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
    </command:parameters>
    <command:inputTypes>
      <command:inputType>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
        </maml:description>
      </command:inputType>
    </command:inputTypes>
    <command:returnValues>
      <!-- OutputType: SnsAdManagedGroup -->
      <command:returnValue>
        <dev:type>
          <maml:name>SnsAdGroupMembers.SnsAdManagedGroup</maml:name>
          <maml:uri />
        </dev:type>
      </command:returnValue>
    </command:returnValues>
    <maml:alertSet>
      <maml:title></maml:title>
      <maml:alert>
        <maml:para>AUTHOR: Svetoslav Nedyalkov Savov</maml:para>
        <maml:para>THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK</maml:para>
        <maml:para>OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.</maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
      </maml:alert>
    </maml:alertSet>
    <command:examples>
      <command:example>
        <maml:title>---------- EXAMPLE 1 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Remove-SnsAdManagedGroup -Identity "Finance Department DL";</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Enumerates The Configuration Object For AD Group "Finance Department DL" And Deletes It.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 2 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Remove-SnsAdManagedGroup "Finance Department", "Sales Department";</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Enumerates The Configuration Objects For AD Groups "Finance Department" And "Sales Department" And Delete Them.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 3 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = "Finance Department DL", "Sales Department DL" | `
Remove-SnsAdManagedGroup -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Enumerates The Configuration Objects For AD Groups "Finance Department DL" And "Sales Department DL" And Delete Them.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
    </command:examples>
    <maml:relatedLinks>
      <maml:navigationLink>
        <maml:linkText> svesavov / SnsPsAdGroupMembers - </maml:linkText>
        <maml:uri>https://github.com/svesavov/SnsPsAdGroupMembers</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> PowerShell Gallery - </maml:linkText>
        <maml:uri>https://www.powershellgallery.com/packages/SnsPsAdGroupMembers/</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> Svetoslav Savov on LinkedIn - </maml:linkText>
        <maml:uri>https://www.linkedin.com/in/svetoslavsavov</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> SQLite V3 - </maml:linkText>
        <maml:uri>https://sqlite.org/index.html</maml:uri>
      </maml:navigationLink>
    </maml:relatedLinks>
  </command:command>
  <!-- Cmdlet: Set-SnsAdManagedGroup -->
  <command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
    <command:details>
      <command:name>Set-SnsAdManagedGroup</command:name>
      <command:verb>Set</command:verb>
      <command:noun>SnsAdManagedGroup</command:noun>
      <maml:description>
        <maml:para>Modifies A Managed Active Directory Group Configuration Entry.</maml:para>
      </maml:description>
    </command:details>
    <maml:description>
      <maml:para>Modifies A Managed Active Directory Group Configuration Entry.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Operation Of "SnsPsAdGroupMembers" PSModule Install It With "AllUsers" Scope. The Idea Behind This Module Is To Be Used On A Scheduled Task "As Service" For The Actual Group Members Management, And Interactively By IT Administrators To Create And Modify The Managed Groups Configuration. This Requires The PSModule To Be Available To Multiple User Accounts.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Creation Of "SnsPsAdGroupMembers" PSModule DataBases, The First Load Of The PSModule Must Be In Elevated Mode. In The Normal Operation The PSModule Does Not Require Elevated Mode. More Information About That Is Provided Further In This Document.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"Why Should I Use This PSModule Instead Of Dynamic Groups?":</maml:para>
      <maml:para>- Well First And Foremost Reason Is Related With The Fact That This PowerShell Module Does Allow To Have Different Logic For Adding And Removing Members. This Is Not Achievable With Dynamic Groups.</maml:para>
      <maml:para>- The Company IT Department Might Need To Use A Single Group For Granting Access Rights In On Premises AD, AzureAD And Use It As Distribution List At The Same Time. Although This Can Be Achieved With Dynamic Groups You Have To Maintain At Least Two Of Them, One For On Premises AD And One For AzureAD.</maml:para>
      <maml:para>- There Are Cases Related With Certain AzureAD Functionalities And Synchronizations With Third Party Cloud Solutions Which Do Not Support Nested And Dynamic Groups. Managing Of Groups With Large Number Of Members In Corporate Environment Without Using Of Group Nestling Could Be Quite Tricky And Related With Lot Of Users Frustration And Administrative Effort.</maml:para>
      <maml:para>- The "SnsPsAdGroupMembers" PSModule Prepare Reports About Modifying Group Members And Audit Of Changes In The Group Management Settings. Whenever A Group Is Used For Granting Sensitive Access Rights Or Managing The Members Of A Sensitive Distribution List, The Group Owners Might Want To Receive Those Reports, Often Immediately After The Above-Mentioned Actions Are Taken.</maml:para>
      <maml:para>- The PSModule Can Be Used Only For Adding Or Only For Removing Members. Using Of Both Is Not Mandatory. This Does Allow Implementation Of Process For Adding Members In Sensitive Groups, Like "Domain Admins" For Example, Following Formal Approval Process, But Removing Members Immediately When The Person Who Owns The Account Leave The Company, Or Change The Position. In This Case There Will Be Zero Tolerance For Users "Forgotten" With More Than Needed Access Rights.</maml:para>
      <maml:para>This PSModule Have The Same Disadvantages And Requirements As The Dynamic Groups. Since The Management Logic Is Based On AD Attribute Values, It Requires The Used Ones To Be Up To Date And Consistent. Some Sort Of Synchronization From The Company HR System Would Address This. Such A Synchronization Is Nice To Have But Not A Requirement. Using My Other PSModule's Will Be Relatively Easy Creation Of Own Synchronization Related With Any On Premises HR Application. Most Of The Cloud Based Ones, Already Have Out Of The Box Synchronization Tools. Creation Of New One Would Not Be Feasible, But It Depends On The API's The Tool Provides.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Manages The Membership Of Active Directory Groups In A Single Domain Forest Based On Predefined Logic About Adding And Removing Members. For That Purpose, The PowerShell Module Uses SQLite Configuration DataBase To Keep Information About:</maml:para>
      <maml:para>- The Managed Groups.</maml:para>
      <maml:para>- The Logic For Adding Members Into Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- The Logic For Removing Members From Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- Explicit Group Inclusions. Those Are AD Objects Which Shall Be Added As Group Members, Although They Do Not Meet The Adding Criteria.</maml:para>
      <maml:para>- Explicit Group Exclusions. Those Are AD Objects Which Shall Not Be Added As Group Members, Although They Do Meet The Adding Criteria.</maml:para>
      <maml:para>- Notification Contacts Who Shall Receive Reports About The Actions And Audit Events Related With Their Own Groups.</maml:para>
      <maml:para>- The PSModule Configuration.</maml:para>
      <maml:para>- Managed Groups Configuration Changes Tracking.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Uses Another SQLite DataBase To Store All The Events Related With The CmdLets Operation And Events Related With Actions Taken On The Managed Groups.</maml:para>
      <maml:para></maml:para>
      <maml:para>To Increase The Confidence In The Automation Among The Group Owners, "SnsPsAdGroupMembers" PSModule Produces Reports Intended To Be Provided To Those Owners, Whenever The PSModule Adds And / Or Removes Members, Whenever It Detects Changes In The Groups Configuration That Might Affect The Group Members, Such Like Changes In The Add Logic, Remove Logic, Explicit Inclusions, Explicit Exclusions And Notification Contacts.</maml:para>
      <maml:para>In Case Of Changes In The Notification Contacts, Both The Old And New Contacts Are Included In The Report Recipients List. The Reports Are Prepared Only When Actual Changes Are Made Or Detected Whenever The Actual Group Management Occur. For That Purpose, The PSModule Uses An SQLite Statistics DataBase To Store Information About:</maml:para>
      <maml:para>- Events Related With Automatic Adding Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Automatic Removing Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Changes In Managed Groups Configuration That Might Affect The Group Membership, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With The Module Operation And Groups Management Intended To Be Provided To The Company IT's. The Internal Events Not Related With Specific Managed Group Are Not Kept In The Statistics DataBase. Therefore The Statistics DataBase Is Not Suitable Source Of Information About Troubleshooting Of Performance, Module Related Issues, And Script Related Issues. However It Is Perfectly Reliable Source Of Troubleshooting Information Related With Troubleshooting Of Incorrect Logic And Any Managed Groups Misconfiguration.</maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Only Prepares Reports And Reverts Them As "SnsReportCollection" Output Object. The Email Relay Options Differ From One Environment To Another, It Is Not Feasible To Maintain Multiple Settings Related With Email Sending In The Configuration DataBase, While Sending Of An Email From PowerShell Is Simple As Running Of A CmdLet. Depending On The Company, Might Be Used Different Languages, Different Wording, Company Branding, Company Stationaries, Company Colors And Company Visual Stylings In The Emails. From That Perspective The PSModule Reverts Reports In Custom Objects And Collections. The User Have To Convert Them To HTML Text And Send Them As Emails, Within The Automation Scripts Which Use "SnsPsAdGroupMembers" Module. The Simplest Way For Doing That Is Using "ConvertTo-Html" And "Send-MailMessage" Native PowerShell CmdLets. Whenever Managed Group Owners Are Not Interested To Receive Any Notifications The Reports For They Own Groups Can Be Disabled Via Leaving Empty The Notification Contacts Setting Of The Group (Or Remove All Notification Contacts For A Managed Group If There Are Already Specified). This Does Not Disable The Logging Of Events Into The Statistics DataBase.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>For DataBase Engine Is Used SQLite. SQLite Is Free Open Source Serverless DataBase, Which Comes With Its Own Advantages And Disadvantages. As Serverless DataBase There Is No Server To Manage The DataBase Requests And Locks. From That Perspective Using A Single SQLite DataBase Either Over Network Or Mapped Drives Or Simultaneously By Multiple Applications / PSSessions Might Lead To Errors In Accessing The DataBase Or DataBase Corruption.</maml:para>
      <maml:para>From That Perspective All The CmdLets Within This Module Have A Feature That Prevents Running Of Those CmdLets In Multiple PowerShell Sessions. All The CmdLets Have Parameter "Force" Which Allows The Usage Of The CmdLets In Multiple PSSessions, Use It At Your Own Risk. The Parameter Is Ignored And Does Not Work When The PSSession Is "As A Service" (In Automation Script Executed With Scheduled Task For Example).</maml:para>
      <maml:para>Both The Configuration And Statistics DataBases Are Located In "C:\ProgramData\SnsAdGroupMembers" By Default. In Order The Folder And DataBase Files To Be Created Properly, The First Run Of This CmdLet To Be Made In Elevated PowerShell Session. Creation Of The DataBase Folder And Setting The Required NTFS Permissions Requires Local Administrator Access Rights. The DataBase Files Can Be Moved / Migrated Into Different Folders, In That Case The Administrator Who Is Doing That Have To Make Sure That The Folder Exists, All The Users That Will Use This PSModule Will Have "Modify" NTFS Permissions Over The Folder And The DataBase Files, Move The DataBase Files Into The New Folder And Properly Provide The Module With The New Folder Absolute (Full) Path.</maml:para>
      <maml:para>Although Using This PSModule On Domain Controllers Is Possible, It Is Against The Best Practices And It Is Not Recommended. All Automations Shall Be Run On Dedicated Virtual Or Physical Machine. From That Perspective It Is Required "Local Admin" Access Rights.</maml:para>
      <maml:para>It Is Not Recommended The DataBase Files To Be Moved, And If That Happen They Shall Be Not Moved On Network Shares Or Mapped Drives. This Will Not Prevent The PSModule To Do Its Job. It Will Introduce Performance Degradation, Possible Interruption In Case Of Network Issues And Eventually Corruption Of The DataBases.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>Never Move DataBases Outside The Default Location When The PSModule Is Installed With Scope "CurrentUser".</maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>"CfgDbFolder" Setting Specifies The Location Of Both Configuration And Statistics DataBases Simultaneously Unless The Statistics DataBase Have Explicitly Specified Location. With Other Words When Modify Configuration DataBase Location And "StatDbFolder" Setting Is Not Used, Both DataBases Have To Be Moved In The New Location.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Contains CmdLets Intended To Be Run Interactively By The User And CmdLets Intended To Be Run Within Automation Scripts On A Schedule As A Service. The CmdLets Intended To Be Used Within Automation Scripts Comply With Additional Requirements Related With Logging, Reporting And Ability To Being Monitored (Using "SnsPsScriptsMonitoring" PSModule For Example). "Invoke-SnsAdGroupMembersManage" Is A CmdLet Intended To Be Used In An Automation Scripts. By Its Nature, This CmdLet Is An Automation Encapsulated Within A CmdLet. The Logs And Events Happening During The CmdLet Run Are Logged In An SQLite DataBase "GroupMembersProvStat.db" Referred Furter As Statistics DataBase. It Could Be Used For Other Reporting Purposes Like Periodical Comprehensive Reports About The Actions Taken By Automation Scripts (This Requires Additional Scripting To Read The DataBase And Prepare The Reports).</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>When Working With Active Directory It Is Important What Identity Attribute Will Be Chosen For Binding To The AD Objects. Although Naturally AD Uses DistinguishedName For Binding And LDAP Queries, It Is Not The Best Possible Identity. The DistinguishedName Is Unique But It Is Not Constant, It Can Be Changed Over The AD Object Life Cycle. An AD Object Can Be Renamed And / Or Moved Into Different Organizational Unit, Or The Organizational Unit Where The Object Is Located Can Be Renamed And / Or Moved. That Will Modify Object's Distinguished Name. In This Case The Active Directory Will Automatically Reflect Those Changes In The Attributes Of The Object And On All Relational Attributes Of The Remaining Objects Which Point To Our Object. For Example "member" Attribute Of All The Groups Where Our AD Object Is Member Of, Or "manager" Attribute Of All Accounts That Our User Is Manager. However AD Will Not Modify Accordingly The PSModule Configuration Stored In An External For The AD DataBase. This Will Lead To Errors And Failures.</maml:para>
      <maml:para>It Is Best Practice The AD Related Applications To Use For Binding Other Identity Attributes Which Do Not Change During The Objects Life Cycle. Those Are "objectGUID" And "objectSid". The Best Practices Gives Preference To The "objectSid" By Various Reasons. Since It Is Possible Groups To Have Member Objects Without "objectSid" (Contact Objects For Example) The "SnsPsAdGroupMembers" PSModule Uses As Identity The "ObjectGUID" Attribute. Thus Way When An Object Is Renamed Or Moved The PSModule Is Not Affected And Continue To Work As Intended.</maml:para>
      <maml:para>The The Well-Known AD Behavior, That When An Object Is Deleted And Then Recreated, All The Access Rights And Group Membership Are Lost, Is Related With The Fact That The Recreated Object Have Different "objectSid". Using The "objectGUID" As Identity Introduces Similar Behavior Of "SnsPsAdGroupMembers". Deletion And Recreation Of An AD Group Object Does Not Automatically Enable It For Automatic Members Management With The Logic Of The Deleted Group.</maml:para>
      <maml:para>The Using "objectGUID" As Identity In The PSModule Configuration Ensures That The PSModule Is Not Affected By Objects Rename Or Objects Move. When A Managed Group, Explicit Inclusion, Explicit Exclusion Is Renamed Or Moved Into Different OU, Their "objectGUID" Remains Intact. And The PSModule Continue To Bind To Those Objects Without Errors. However This Does Introduce Additional Overhead For The CmdLets Intended To Manage The Groups Configuration. When An Object Is Provided To Them They Need To Search For That Object In Active Directory, Enumerate The "objectGUID" Of The Object And Specify The Enumerated Value Into The Configuration DataBase. Since The CmdLets Query AD, That Query Can Be Made Against Multiple Attributes, Which Does Provide Freedom For The User To Use Multitude Of Values When An AD Object Is Provided To A Parameter. Please Refer To Each To The Parameters Sections Of Each CmdLet Help Document.</maml:para>
      <maml:para>When LDAP Queries Are Needed The Things Get More Complicated. The LDAP Queries Work Only With DistinguishedName. When You Need To Query About Reports Of A Person, Or Members Of A Group The AD Expects LDAP Query With DistinguishedName Values. An Example Of Often Use LDAP Query Clause Is:</maml:para>
      <maml:para>"(manager=CN=Jane Smith,CN=Users,DC=contoso,DC=com)"</maml:para>
      <maml:para>If "SnsPsAdGroupMembers" PSModule Keep It As Is Into The Configuration, In Case Of DistinguishedName Change, The Logic Will Revert No Results, Which Might Lead To Removal Of All The Members From The Group. Instead The LDAP Clause Is Stored Like:</maml:para>
      <maml:para>"(manager=00000000-0000-0000-0000-000000000000)"</maml:para>
      <maml:para>This Complicates The PSModule Further, As On The AD Managed Group Configuration Creation / Modification It Have To Evaluate The Specified Parameters, Match Them Using RegEx Pattern About Any Distinguished Names, Bind To The AD Object Using The Matched DistinguishedName, Enumerates The AD Object "objectGUID" And Amend The Matched DistinguishedName With The Enumerated "objectGUID". And Before The Actual AD Managed Group Members Management, It Have To Evaluate The Configuration About "objectGUID" Values Using RegEx Matching, Bind To The AD Object Using The Matched "objectGUID", Enumerate The AD Object DistinguishedName And Amend The "objectGUID" With The Enumerated DistinguishedName. Thus Way Introducing Overhead For The PSModule And For The Domain Controller Which Serves The LDAP Requests.</maml:para>
      <maml:para>To Reduce The Number Of The AD Requests And The Overhead, The PSModule Caches The Attributes Of The Previously Bind To Or Queried About AD Objects, And Consequently Uses The Cache Instead Of Making New AD Requests. The Effectiveness Of The AD Cache Depends On The Similarities In The Configuration Of The Groups.</maml:para>
      <maml:para>The Attributes Modified By The "SnsPsAdGroupMembers" PSModule Like "memberOf" AD Attribute, Are Never Cached. Caching Those Might Lead To False Positive Or Real Errors.</maml:para>
      <maml:para>The Values Of The AD Attributes Without Requirements For Uniqueness Cannot Be Used For Indexing And Searches In The Cache. For Example There Is No Uniqueness Requirement For "cn" Attribute, You Can Have Multiple Objects With The Same "cn" As Long As They Are Located In Different OU's. When A CmdLet Parameter From The PSModule Is Provided With "cn" Value, It Must Make LDAP Search To Enumerate The AD Object, Either To Confirm That The Value Corresponds To An AD Object Or To Throw Error About Multiple Objects. In Case We Have The Specified Value In The Cache It Is Not Certain That There Are No Other Objects With The Same Value In The AD Domain. Whenever We Use AD Attributes With Uniqueness Requirements Like Distinguished Name, For Example Presence Of The Provided Value In The Cache Can Be Safely Assumed As Correct And Unique, In That Case Query Against The AD Domain Is Not Needed. Usage Of Values In Attributes Without Uniqueness Requirements Reduces The Effectiveness Of The AD Cache Feature Further.</maml:para>
      <maml:para>Introducing A Cache In The PSModule Introduces All Generic Disadvantages Related With Caching, Like Cached Outdated Values. The "SnsPsAdGroupMembers" PSModule Keeps The AD Cache In The System Memory. This Does Ensure Maximum Speed For Accessing The Cache, With Negative Impact On The Machine Performance Because Of The Increased Memory Usage. Together With The Feature Which Does Not Allow Usage Of The PSModule In Multiple PSSession (Which Actually Force The Users To Close Their PSSessions Once They Finish Their Job), Ensures Relatively Short Life Span Of The Cached Entries, Thus Way Reducing The Cache Effectiveness But Increasing The Reliability Via Minimizing The Possibility For Issues Related With Outdated Entries.</maml:para>
      <maml:para>Although The Shorter Lifespan Of The Cached Entries Reduces The Possibility For Mistakes, It Does Not Eliminate Them Completely. Mistakes Might Happen Without Corrupted Or Outdated Cached Entry. Let Us Assume We Have A Department Related Group Where Members Are Added Based On Specific Value In The Department AD Attribute And Removed When The Value Is Different. At The Same Time, The Department AD Attribute Is Automatically Synchronized From The Company HR System. In Case Of Department Rebranding The Sync From The HR System Will Modify The Attribute Value Of All Department Members. In That Case All The Department Members Will Be Removed From The Group. This Is Addressed With Introducing Of New Feature Which Prevents Any Members Removal Whenever The Members Enumerated For Removing Are More Than Certain Threshold. The Threshold Is Configurable. The Default Value Is 50%.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" Provides A Feature Intended For Quick Identifying Whether A Group Is Automatically Managed Or Not, Which Is Disabled By Default. It Could Be Very Annoying And Frustrating To Manually Add Or Remove A Member Into A Group And The Automation To Revert The Changes Back Because The Member Does Not Match The Adding Or Match The Removing Criteria For The Automatic Group Members Management. Normally The IT Administrators Would Need To Check In The PS Module Configuration To Verify Whether An AD Group Is Automatically Managed Using The PSModule Before Membership Modification. This Might Lead To Failed Scheduled Tasks Due To Multiple PSSessions With The PSModule Loaded. From That Perspective "SnsPsAdGroupMembers" Stores A Predefined Constant Value In A Predefined AD Attribute Of The AD Managed Groups And Clears The Predefined Constant Value From The Predefined AD Attribute Of The Not Managed Groups. Therefore The Company IT Administrators Just Need To Look At That Attribute Before Manually Add Or Remove Groups Members In An AD Group.</maml:para>
      <maml:para>To Enable This Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet, To Specify An AD Attribute And A Constant Value Which Shall Be Set On The AD Managed Groups. To Disable That Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet To Clear Either The Value Or The AD Attribute Used By This Feature Or Both. When Enabled On A Scheduled Job After Actual Group Management "Invoke-SnsAdGroupMembersManage" Sets The Predefined Constant Value Into The Predefined AD Attribute Of All Enabled AD Managed Groups And Clears The Value From All Not Managed AD Groups. Therefore Once The Feature Is Disabled The User Have To Manually Clear The Value From The AD Attribute Of All The Groups In Case The Feature Was Ever Used. Changing The Attribute Will Not Clear The Value From The Old Attribute.</maml:para>
      <maml:para>NOTE: This Feature Considers As Managed Only The Groups That Are Enabled In The Groups Configuration. Disabling A Group From Automatic Members Management, Even Temporary Will Clear The AD Attribute Used By This Feature, Indicating To The Corporate IT Administrators, That The Group Membership Can Be Managed Manually.</maml:para>
      <maml:para>NOTE: This Feature Can Use Only AD Attributes With Type Of Single Valued String.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>Set-SnsAdManagedGroup Is Intended To Be Used Interactively By A User To Modify A Managed AD Group Configuration Entry In The Configuration DataBase.</maml:para>
      <maml:para>NOTE: Please Make Sure That The PowerShell Is Closed, When You Finish With The Work On The Managed AD Groups Configuration. Otherwise Either The Other Users Or Any Automated Task Will Be Prevented From Work With The PSModule.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In Parameters Validation The CmdLet Query The Configuration DataBase And Enumerates The Provided By The User Objects. In Case The Specified Objects Does Not Exists The CmdLet Throws Error. The Parameters Which Accept Wildcard Usage Requires To Identify Unambiguously The Specified Object. Therefore If A Specified Wildcard Pattern Revert More Than One Object, The CmdLet Will Throw Error. Use The Wildcards Only To Spare Typing When You Are Completely Sure It Will Revert Single Object.</maml:para>
      <maml:para>The Validation Of "AddLogic" And "RemoveLogic" Parameters, Treat The Specified Values As LDAP Query And Executes Them Against AD. If The LDAP Query Revert No Results The Validation Fails. This Reduces The CmdLet Performance And Slows It Down, But It Is Not Intended To Be Used On Regular Basis Or Within Automation Scripts Anyway. So The Reduced Performance Is Acceptable In This Case. When The CmdLet Connects To A Domain Controller In The Same Subnet The Reduced Performance Is Not Noticeable By The User.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "BeginProcessing" Method "Set-SnsAdManagedGroup" CmdLet Initializes The PSModule Configuration. Verifies The Existence, The Schema And The Integrity Of The Configuration DataBase. Verifies About Other PowerShell Processes Using "SnsPsAdGroupMembers" PSModule.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "ProcessRecord" Method "Set-SnsAdManagedGroup" CmdLet Performs Additional Verifications Which Cannot Be Made During The Parameters Validation. "AddLogic" And "RemoveLogic" Parameters Are Not Mandatory To Allow The User To Configure A Group Only For Adding Or Only For Removing Members, However Where Both Are Missing The Group Will Be Not Managed At All. Normally This Cannot Be Verified During The Parameters Validation As The CmdLet Accepts The Parameters In The Order Specified By The User. Therefore The User Might Specify The "RemoveLogic" Before The "AddLogic" Which Will Cause False Positives On Any Parameter Validation From This Kind. Afterward The CmdLet Modifies The AD Managed Group Properties That Correspond To The Specified By The User CmdLet Parameters. Since The CmdLet Is Intended To Be Used On Existing Groups, The Parameters For Managing Explicit Inclusions, Explicit Exclusions And Notification Contacts Are Not Present Here. Instead You Can Use The Corresponding CmdLets. Then The CmdLet Sends To The PowerShell Pipeline The Modified AD Managed Group Objects.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The CmdLet Reverts SnsAdManagedGroup Objects With The Following Properties And Methods:</maml:para>
      <maml:para>- "Position" Property Of Type Integer. Represents The Group Position In The Collection For Members Management.</maml:para>
      <maml:para>- "Identity" Property Of Type Guid. Represents The Managed Group AD "objectGUID".</maml:para>
      <maml:para>- "Name" Property Of Type String. Contains The Value Of The Managed Group "cn" Attribute.</maml:para>
      <maml:para>- "AddLogic" Property Of Type String. Contains The Logic For Adding Members Into The Managed Group.</maml:para>
      <maml:para>- "RemoveLogic" Property Of Type String. Contains The Logic For Removing Members From The Managed Group.</maml:para>
      <maml:para>- "Inclusions" Property Of Type SnsAdManagedGroupInclusion Array. Contains An Array With The Group's Explicit Inclusions. Each SnsAdManagedGroupInclusion Object Contains: "Identity" Property Of Type Guid. "Name" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Exclusions" Property Of Type SnsAdManagedGroupExclusion Array. Contains An Array With The Group's Explicit Exclusions. Each SnsAdManagedGroupExclusion Object Contains: "Identity" Property Of Type Guid. "Name" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Notify" Property Of Type SnsAdManagedGroupContact Array. Contains An Array With The Group's Notification Contacts. Each SnsAdManagedGroupContact Object Contains: "Email" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Enabled" Property Of Type Boolean. Represents Whether The Managed Group Entry Is Active Or Not.</maml:para>
      <maml:para>- "GetSnsRawAddLogic" Method Intended To Revert The Not Normalized Add Logic As It Is Set In The Group Configuration.</maml:para>
      <maml:para>- "GetSnsRawRemoveLogic" Method Intended To Revert The Not Normalized Remove Logic As It Is Set In The Group Configuration.</maml:para>
    </maml:description>
    <command:syntax>
      <!-- Parameter set: __AllParameterSets -->
      <command:syntaxItem>
        <maml:name>Set-SnsAdManagedGroup</maml:name>
        <!-- Parameter: Identity -->
        <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
          <maml:name>Identity</maml:name>
          <maml:description>
            <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
            <maml:para>The Parameter Accepts The Following Values:</maml:para>
            <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
            <maml:para>- objectGUID</maml:para>
            <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
            <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
            <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
            <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          </maml:description>
          <command:parameterValue required="true">object</command:parameterValue>
          <dev:type>
            <maml:name>System.Object</maml:name>
            <maml:uri />
          </dev:type>
        </command:parameter>
        <!-- Parameter: AddLogic -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>AddLogic</maml:name>
          <maml:description>
            <maml:para>Specifies The Logic For Adding Members Of The AD Managed Group.</maml:para>
            <maml:para>The Logic Is Active Directory Attributes Based And Must Comply With The Lightweight Directory Access Protocol (LDAP) Query Language.</maml:para>
            <maml:para>For Best Results I Would Recommend Usage Of Attributes Which Values Are Automatically Maintained, For Example With A Synchronization From An HR Tool.</maml:para>
            <maml:para></maml:para>
            <maml:para></maml:para>
            <maml:para>The Provided Value Will Be Used On The Group Members Adding As Follows:</maml:para>
            <maml:para>"(&amp;(objectCategory=person)(objectClass=user)(!(memberOf=[ADManagedGroupDn]))[AddLogic])"</maml:para>
            <maml:para>During The Parameter Validation The CmdLet Will Actually Execute The Following LDAP Query:</maml:para>
            <maml:para>"(&amp;(objectCategory=person)(objectClass=user)[AddLogic])"</maml:para>
            <maml:para>Therefore The Value Specified To The Parameter Must Have The Following Syntax "([Attribute1]=[Value1])"</maml:para>
            <maml:para></maml:para>
            <maml:para>Whenever You Need To Specify Multiple Conditions And The Added Member Must Comply With All Of Them (AND Logic) You Need Not To Specify AND. The Logic Must Looks Like "([Attribute1]=[Value1])([Attribute2]=[Value2])".</maml:para>
            <maml:para>For Example When You Need All Enabled Users With Mailboxes From "Finance Department" To Be Added In A Group The Logic Has To Looks Like:</maml:para>
            <maml:para>"(department=Finance Department)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)"</maml:para>
            <maml:para></maml:para>
            <maml:para>Whenever You Need To Specify Multiple Conditions With OR Logic. You Need To Specify That. The Logic Must Looks Like "(|([Attribute1]=[Value1])([Attribute2]=[Value2]))".</maml:para>
            <maml:para>For Example When You Need All Enabled Users With Mailboxes From "Finance Department" And "Sales Department" To Be Added In A Group The Logic Has To Looks Like:</maml:para>
            <maml:para>"(|(department=Finance*)(department=Sales*))(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)"</maml:para>
            <maml:para></maml:para>
            <maml:para></maml:para>
            <maml:para>To Save You Time Researching In Internet About The Correct Syntax For Reference LDAP extensibleMatch Rules OID's When They Are Needed, You Can Use:</maml:para>
            <maml:para>- :Band: When You Need LDAP_MATCHING_RULE_BIT_AND (:1.2.840.113556.1.4.803:)</maml:para>
            <maml:para>- :Bor: When You Need LDAP_MATCHING_RULE_BIT_OR (:1.2.840.113556.1.4.804:)</maml:para>
            <maml:para>- :Expand: When You Need LDAP_MATCHING_RULE_TRANSITIVE_EVAL (:1.2.840.113556.1.4.1941:)</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
        <!-- Parameter: DomainController -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>DomainController</maml:name>
          <maml:description>
            <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
            <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
            <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
            <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
            <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
        <!-- Parameter: Enabled -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>Enabled</maml:name>
          <maml:description>
            <maml:para>Specifies To Disable The New AD Managed Group Configuration Entry.</maml:para>
            <maml:para>Disabled AD Managed Groups Are Not Processed By "Invoke-SnsAdGroupMembersManage".</maml:para>
          </maml:description>
          <command:parameterValue required="true">bool</command:parameterValue>
          <dev:type>
            <maml:name>System.Boolean</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>True</dev:defaultValue>
        </command:parameter>
        <!-- Parameter: Force -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>Force</maml:name>
          <maml:description>
            <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
        <!-- Parameter: Position -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named" aliases="OrderPosition">
          <maml:name>Position</maml:name>
          <maml:description>
            <maml:para>Specifies The Position For The New AD Managed Group.</maml:para>
            <maml:para>"Invoke-SnsAdGroupMembersManage" CmdLet Process The AD Managed Groups In Ascending Order (In Sequence) Based On The AD Managed Group Position. Whenever There Are Dependencies Between The Groups, The Prerequisite Group Have To Be Processed Before The Dependent Group (Must Have Lesser Position). Otherwise The Dependent Group Will Use As Input Outdated Information.</maml:para>
            <maml:para>This Is Not Critical Though On The Next Run The Dependent Groups Will Have The Proper Input Because The Prerequisite Group Will Be Updated (On The Current Run). Wrong Sequence Just Slows Down The Group Members Management.</maml:para>
          </maml:description>
          <command:parameterValue required="true">int</command:parameterValue>
          <dev:type>
            <maml:name>System.Int32</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>-1</dev:defaultValue>
        </command:parameter>
        <!-- Parameter: RemoveLogic -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>RemoveLogic</maml:name>
          <maml:description>
            <maml:para>Specifies The Logic For Removing Members From The AD Managed Group.</maml:para>
            <maml:para>The Logic Is Active Directory Attributes Based And Must Comply With The Lightweight Directory Access Protocol (LDAP) Query Language.</maml:para>
            <maml:para>For Best Results I Would Recommend Usage Of Attributes Which Values Are Automatically Maintained, For Example With A Synchronization From An HR Tool.</maml:para>
            <maml:para></maml:para>
            <maml:para></maml:para>
            <maml:para>The Provided Value Will Be Used On The Group Members Removing As Follows:</maml:para>
            <maml:para>"(&amp;[RemoveLdapQuery](memberOf=[ADManagedGroupDn]))"</maml:para>
            <maml:para>During The Parameter Validation The CmdLet Will Actually Execute The Following LDAP Query:</maml:para>
            <maml:para>"(&amp;(objectCategory=person)(objectClass=user)[RemoveLdapQuery])"</maml:para>
            <maml:para></maml:para>
            <maml:para>Unlike The AddLogic Here You Most Likely Will Need To Use OR Logic Only. Therefore You Need To Specify The Logic As Follows:</maml:para>
            <maml:para>"(|(!(Attribute1=Value1))(!(Attribute2=Value2)))"</maml:para>
            <maml:para></maml:para>
            <maml:para>For Example When You Need To Remove Users From A Group:</maml:para>
            <maml:para>- When They Are No Longer In "Finance Department" Or "Sales Department".</maml:para>
            <maml:para>- When Their Accounts Get Disabled.</maml:para>
            <maml:para>- When Their Mailboxes Are Disabled.</maml:para>
            <maml:para>"(|(!(|(department=Finance*)(department=Sales*)))(userAccountControl:1.2.840.113556.1.4.803:=2)(!(mail=*)))"</maml:para>
            <maml:para>For RemoveLogic It Just Does Not Make Sense To Use AND Logic. At The End We Need To Remove The Members When One Of The Conditions Occur. It Is Not Likely All Of The Conditions To Occur Simultaneously To Remove A Member.</maml:para>
            <maml:para>NOTE: Unlike The AddLogic The RemoveLogic Actually Does Not Add The Conditions The Removed Object To Be A User Account. Which Means That "SnsPsAdGroupMembers" PSModule Actually Does Remove Group And Contact Member Objects. When You Prepare Your RemoveLogic Please Pay Attention That The Different AD Objects Have Different Sets Of Attributes. For Example If You Have Condition (!(userPrincipalName=*)) This Would Automatically Remove All The Nested Groups And Contacts, Because They Have No UPN Attribute.</maml:para>
            <maml:para></maml:para>
            <maml:para></maml:para>
            <maml:para>To Save You Time Researching In Internet About The Correct Syntax For Reference LDAP extensibleMatch Rules OID's When They Are Needed, You Can Use:</maml:para>
            <maml:para>- :Band: When You Need LDAP_MATCHING_RULE_BIT_AND (:1.2.840.113556.1.4.803:)</maml:para>
            <maml:para>- :Bor: When You Need LDAP_MATCHING_RULE_BIT_OR (:1.2.840.113556.1.4.804:)</maml:para>
            <maml:para>- :Expand: When You Need LDAP_MATCHING_RULE_TRANSITIVE_EVAL (:1.2.840.113556.1.4.1941:)</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
    <command:parameters>
      <!-- Parameter: Identity -->
      <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
        <maml:name>Identity</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
        <maml:name>Group</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>This is an alias of the Identity parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
        <maml:name>ManagedGroup</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>This is an alias of the Identity parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <!-- Parameter: AddLogic -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>AddLogic</maml:name>
        <maml:description>
          <maml:para>Specifies The Logic For Adding Members Of The AD Managed Group.</maml:para>
          <maml:para>The Logic Is Active Directory Attributes Based And Must Comply With The Lightweight Directory Access Protocol (LDAP) Query Language.</maml:para>
          <maml:para>For Best Results I Would Recommend Usage Of Attributes Which Values Are Automatically Maintained, For Example With A Synchronization From An HR Tool.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
          <maml:para>The Provided Value Will Be Used On The Group Members Adding As Follows:</maml:para>
          <maml:para>"(&amp;(objectCategory=person)(objectClass=user)(!(memberOf=[ADManagedGroupDn]))[AddLogic])"</maml:para>
          <maml:para>During The Parameter Validation The CmdLet Will Actually Execute The Following LDAP Query:</maml:para>
          <maml:para>"(&amp;(objectCategory=person)(objectClass=user)[AddLogic])"</maml:para>
          <maml:para>Therefore The Value Specified To The Parameter Must Have The Following Syntax "([Attribute1]=[Value1])"</maml:para>
          <maml:para></maml:para>
          <maml:para>Whenever You Need To Specify Multiple Conditions And The Added Member Must Comply With All Of Them (AND Logic) You Need Not To Specify AND. The Logic Must Looks Like "([Attribute1]=[Value1])([Attribute2]=[Value2])".</maml:para>
          <maml:para>For Example When You Need All Enabled Users With Mailboxes From "Finance Department" To Be Added In A Group The Logic Has To Looks Like:</maml:para>
          <maml:para>"(department=Finance Department)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)"</maml:para>
          <maml:para></maml:para>
          <maml:para>Whenever You Need To Specify Multiple Conditions With OR Logic. You Need To Specify That. The Logic Must Looks Like "(|([Attribute1]=[Value1])([Attribute2]=[Value2]))".</maml:para>
          <maml:para>For Example When You Need All Enabled Users With Mailboxes From "Finance Department" And "Sales Department" To Be Added In A Group The Logic Has To Looks Like:</maml:para>
          <maml:para>"(|(department=Finance*)(department=Sales*))(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)"</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
          <maml:para>To Save You Time Researching In Internet About The Correct Syntax For Reference LDAP extensibleMatch Rules OID's When They Are Needed, You Can Use:</maml:para>
          <maml:para>- :Band: When You Need LDAP_MATCHING_RULE_BIT_AND (:1.2.840.113556.1.4.803:)</maml:para>
          <maml:para>- :Bor: When You Need LDAP_MATCHING_RULE_BIT_OR (:1.2.840.113556.1.4.804:)</maml:para>
          <maml:para>- :Expand: When You Need LDAP_MATCHING_RULE_TRANSITIVE_EVAL (:1.2.840.113556.1.4.1941:)</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: RemoveLogic -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>RemoveLogic</maml:name>
        <maml:description>
          <maml:para>Specifies The Logic For Removing Members From The AD Managed Group.</maml:para>
          <maml:para>The Logic Is Active Directory Attributes Based And Must Comply With The Lightweight Directory Access Protocol (LDAP) Query Language.</maml:para>
          <maml:para>For Best Results I Would Recommend Usage Of Attributes Which Values Are Automatically Maintained, For Example With A Synchronization From An HR Tool.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
          <maml:para>The Provided Value Will Be Used On The Group Members Removing As Follows:</maml:para>
          <maml:para>"(&amp;[RemoveLdapQuery](memberOf=[ADManagedGroupDn]))"</maml:para>
          <maml:para>During The Parameter Validation The CmdLet Will Actually Execute The Following LDAP Query:</maml:para>
          <maml:para>"(&amp;(objectCategory=person)(objectClass=user)[RemoveLdapQuery])"</maml:para>
          <maml:para></maml:para>
          <maml:para>Unlike The AddLogic Here You Most Likely Will Need To Use OR Logic Only. Therefore You Need To Specify The Logic As Follows:</maml:para>
          <maml:para>"(|(!(Attribute1=Value1))(!(Attribute2=Value2)))"</maml:para>
          <maml:para></maml:para>
          <maml:para>For Example When You Need To Remove Users From A Group:</maml:para>
          <maml:para>- When They Are No Longer In "Finance Department" Or "Sales Department".</maml:para>
          <maml:para>- When Their Accounts Get Disabled.</maml:para>
          <maml:para>- When Their Mailboxes Are Disabled.</maml:para>
          <maml:para>"(|(!(|(department=Finance*)(department=Sales*)))(userAccountControl:1.2.840.113556.1.4.803:=2)(!(mail=*)))"</maml:para>
          <maml:para>For RemoveLogic It Just Does Not Make Sense To Use AND Logic. At The End We Need To Remove The Members When One Of The Conditions Occur. It Is Not Likely All Of The Conditions To Occur Simultaneously To Remove A Member.</maml:para>
          <maml:para>NOTE: Unlike The AddLogic The RemoveLogic Actually Does Not Add The Conditions The Removed Object To Be A User Account. Which Means That "SnsPsAdGroupMembers" PSModule Actually Does Remove Group And Contact Member Objects. When You Prepare Your RemoveLogic Please Pay Attention That The Different AD Objects Have Different Sets Of Attributes. For Example If You Have Condition (!(userPrincipalName=*)) This Would Automatically Remove All The Nested Groups And Contacts, Because They Have No UPN Attribute.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
          <maml:para>To Save You Time Researching In Internet About The Correct Syntax For Reference LDAP extensibleMatch Rules OID's When They Are Needed, You Can Use:</maml:para>
          <maml:para>- :Band: When You Need LDAP_MATCHING_RULE_BIT_AND (:1.2.840.113556.1.4.803:)</maml:para>
          <maml:para>- :Bor: When You Need LDAP_MATCHING_RULE_BIT_OR (:1.2.840.113556.1.4.804:)</maml:para>
          <maml:para>- :Expand: When You Need LDAP_MATCHING_RULE_TRANSITIVE_EVAL (:1.2.840.113556.1.4.1941:)</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: Position -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named" aliases="OrderPosition">
        <maml:name>Position</maml:name>
        <maml:description>
          <maml:para>Specifies The Position For The New AD Managed Group.</maml:para>
          <maml:para>"Invoke-SnsAdGroupMembersManage" CmdLet Process The AD Managed Groups In Ascending Order (In Sequence) Based On The AD Managed Group Position. Whenever There Are Dependencies Between The Groups, The Prerequisite Group Have To Be Processed Before The Dependent Group (Must Have Lesser Position). Otherwise The Dependent Group Will Use As Input Outdated Information.</maml:para>
          <maml:para>This Is Not Critical Though On The Next Run The Dependent Groups Will Have The Proper Input Because The Prerequisite Group Will Be Updated (On The Current Run). Wrong Sequence Just Slows Down The Group Members Management.</maml:para>
        </maml:description>
        <command:parameterValue required="true">int</command:parameterValue>
        <dev:type>
          <maml:name>System.Int32</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>-1</dev:defaultValue>
      </command:parameter>
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named" aliases="OrderPosition">
        <maml:name>OrderPosition</maml:name>
        <maml:description>
          <maml:para>Specifies The Position For The New AD Managed Group.</maml:para>
          <maml:para>"Invoke-SnsAdGroupMembersManage" CmdLet Process The AD Managed Groups In Ascending Order (In Sequence) Based On The AD Managed Group Position. Whenever There Are Dependencies Between The Groups, The Prerequisite Group Have To Be Processed Before The Dependent Group (Must Have Lesser Position). Otherwise The Dependent Group Will Use As Input Outdated Information.</maml:para>
          <maml:para>This Is Not Critical Though On The Next Run The Dependent Groups Will Have The Proper Input Because The Prerequisite Group Will Be Updated (On The Current Run). Wrong Sequence Just Slows Down The Group Members Management.</maml:para>
          <maml:para>This is an alias of the Position parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">int</command:parameterValue>
        <dev:type>
          <maml:name>System.Int32</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>-1</dev:defaultValue>
      </command:parameter>
      <!-- Parameter: Enabled -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>Enabled</maml:name>
        <maml:description>
          <maml:para>Specifies To Disable The New AD Managed Group Configuration Entry.</maml:para>
          <maml:para>Disabled AD Managed Groups Are Not Processed By "Invoke-SnsAdGroupMembersManage".</maml:para>
        </maml:description>
        <command:parameterValue required="true">bool</command:parameterValue>
        <dev:type>
          <maml:name>System.Boolean</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>True</dev:defaultValue>
      </command:parameter>
      <!-- Parameter: DomainController -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>DomainController</maml:name>
        <maml:description>
          <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
          <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
          <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
          <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
          <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: Force -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>Force</maml:name>
        <maml:description>
          <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
        </maml:description>
        <command:parameterValue required="true">SwitchParameter</command:parameterValue>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
    </command:parameters>
    <command:inputTypes>
      <command:inputType>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
        </maml:description>
      </command:inputType>
    </command:inputTypes>
    <command:returnValues>
      <!-- OutputType: SnsAdManagedGroup -->
      <command:returnValue>
        <dev:type>
          <maml:name>SnsAdGroupMembers.SnsAdManagedGroup</maml:name>
          <maml:uri />
        </dev:type>
      </command:returnValue>
    </command:returnValues>
    <maml:alertSet>
      <maml:title></maml:title>
      <maml:alert>
        <maml:para>AUTHOR: Svetoslav Nedyalkov Savov</maml:para>
        <maml:para>THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK</maml:para>
        <maml:para>OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.</maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
      </maml:alert>
    </maml:alertSet>
    <command:examples>
      <command:example>
        <maml:title>---------- EXAMPLE 1 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Set-SnsAdManagedGroup -Identity "Finance Department DL" `
-AddLogic "(department=Finance Department)(!(userAccountControl:Band:=2))(mail=*)" `
-RemoveLogic "(|(!(department=Finance*))(userAccountControl:Band:=2)(!(mail=*)))";</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Modifies The "AddLogic" And "RemoveLogic" Of The Managed AD Group Configuration Object For "Finance Department DL" Active Directory Group.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 2 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Set-SnsAdManagedGroup -Identity "Finance Department DL" `
-Enabled:$false -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Disables The Managed AD Group Configuration Object For "Finance Department DL" Active Directory Group.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 3 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Set-SnsAdManagedGroup -Identity "Finance Department DL" `
-Position 0 -Confirm;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Modifies The Position Of The Managed AD Group Configuration Object For "Finance Department DL" Active Directory Group. On The Process The User Will Be Asked For Confirmation. With Position 0 The AD Managed Group Will Be The First Processed By "Invoke-SnsAdGroupMembersManage" CmdLet.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
    </command:examples>
    <maml:relatedLinks>
      <maml:navigationLink>
        <maml:linkText> svesavov / SnsPsAdGroupMembers - </maml:linkText>
        <maml:uri>https://github.com/svesavov/SnsPsAdGroupMembers</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> PowerShell Gallery - </maml:linkText>
        <maml:uri>https://www.powershellgallery.com/packages/SnsPsAdGroupMembers/</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> Svetoslav Savov on LinkedIn - </maml:linkText>
        <maml:uri>https://www.linkedin.com/in/svetoslavsavov</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> SQLite V3 - </maml:linkText>
        <maml:uri>https://sqlite.org/index.html</maml:uri>
      </maml:navigationLink>
    </maml:relatedLinks>
  </command:command>
  <!-- Cmdlet: Add-SnsAdManagedGroupContact -->
  <command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
    <command:details>
      <command:name>Add-SnsAdManagedGroupContact</command:name>
      <command:verb>Add</command:verb>
      <command:noun>SnsAdManagedGroupContact</command:noun>
      <maml:description>
        <maml:para>Add Specified Email As Managed Active Directory Group Notification Contact.</maml:para>
      </maml:description>
    </command:details>
    <maml:description>
      <maml:para>Add Specified Email As Managed Active Directory Group Notification Contact.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Operation Of "SnsPsAdGroupMembers" PSModule Install It With "AllUsers" Scope. The Idea Behind This Module Is To Be Used On A Scheduled Task "As Service" For The Actual Group Members Management, And Interactively By IT Administrators To Create And Modify The Managed Groups Configuration. This Requires The PSModule To Be Available To Multiple User Accounts.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Creation Of "SnsPsAdGroupMembers" PSModule DataBases, The First Load Of The PSModule Must Be In Elevated Mode. In The Normal Operation The PSModule Does Not Require Elevated Mode. More Information About That Is Provided Further In This Document.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"Why Should I Use This PSModule Instead Of Dynamic Groups?":</maml:para>
      <maml:para>- Well First And Foremost Reason Is Related With The Fact That This PowerShell Module Does Allow To Have Different Logic For Adding And Removing Members. This Is Not Achievable With Dynamic Groups.</maml:para>
      <maml:para>- The Company IT Department Might Need To Use A Single Group For Granting Access Rights In On Premises AD, AzureAD And Use It As Distribution List At The Same Time. Although This Can Be Achieved With Dynamic Groups You Have To Maintain At Least Two Of Them, One For On Premises AD And One For AzureAD.</maml:para>
      <maml:para>- There Are Cases Related With Certain AzureAD Functionalities And Synchronizations With Third Party Cloud Solutions Which Do Not Support Nested And Dynamic Groups. Managing Of Groups With Large Number Of Members In Corporate Environment Without Using Of Group Nestling Could Be Quite Tricky And Related With Lot Of Users Frustration And Administrative Effort.</maml:para>
      <maml:para>- The "SnsPsAdGroupMembers" PSModule Prepare Reports About Modifying Group Members And Audit Of Changes In The Group Management Settings. Whenever A Group Is Used For Granting Sensitive Access Rights Or Managing The Members Of A Sensitive Distribution List, The Group Owners Might Want To Receive Those Reports, Often Immediately After The Above-Mentioned Actions Are Taken.</maml:para>
      <maml:para>- The PSModule Can Be Used Only For Adding Or Only For Removing Members. Using Of Both Is Not Mandatory. This Does Allow Implementation Of Process For Adding Members In Sensitive Groups, Like "Domain Admins" For Example, Following Formal Approval Process, But Removing Members Immediately When The Person Who Owns The Account Leave The Company, Or Change The Position. In This Case There Will Be Zero Tolerance For Users "Forgotten" With More Than Needed Access Rights.</maml:para>
      <maml:para>This PSModule Have The Same Disadvantages And Requirements As The Dynamic Groups. Since The Management Logic Is Based On AD Attribute Values, It Requires The Used Ones To Be Up To Date And Consistent. Some Sort Of Synchronization From The Company HR System Would Address This. Such A Synchronization Is Nice To Have But Not A Requirement. Using My Other PSModule's Will Be Relatively Easy Creation Of Own Synchronization Related With Any On Premises HR Application. Most Of The Cloud Based Ones, Already Have Out Of The Box Synchronization Tools. Creation Of New One Would Not Be Feasible, But It Depends On The API's The Tool Provides.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Manages The Membership Of Active Directory Groups In A Single Domain Forest Based On Predefined Logic About Adding And Removing Members. For That Purpose, The PowerShell Module Uses SQLite Configuration DataBase To Keep Information About:</maml:para>
      <maml:para>- The Managed Groups.</maml:para>
      <maml:para>- The Logic For Adding Members Into Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- The Logic For Removing Members From Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- Explicit Group Inclusions. Those Are AD Objects Which Shall Be Added As Group Members, Although They Do Not Meet The Adding Criteria.</maml:para>
      <maml:para>- Explicit Group Exclusions. Those Are AD Objects Which Shall Not Be Added As Group Members, Although They Do Meet The Adding Criteria.</maml:para>
      <maml:para>- Notification Contacts Who Shall Receive Reports About The Actions And Audit Events Related With Their Own Groups.</maml:para>
      <maml:para>- The PSModule Configuration.</maml:para>
      <maml:para>- Managed Groups Configuration Changes Tracking.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Uses Another SQLite DataBase To Store All The Events Related With The CmdLets Operation And Events Related With Actions Taken On The Managed Groups.</maml:para>
      <maml:para></maml:para>
      <maml:para>To Increase The Confidence In The Automation Among The Group Owners, "SnsPsAdGroupMembers" PSModule Produces Reports Intended To Be Provided To Those Owners, Whenever The PSModule Adds And / Or Removes Members, Whenever It Detects Changes In The Groups Configuration That Might Affect The Group Members, Such Like Changes In The Add Logic, Remove Logic, Explicit Inclusions, Explicit Exclusions And Notification Contacts.</maml:para>
      <maml:para>In Case Of Changes In The Notification Contacts, Both The Old And New Contacts Are Included In The Report Recipients List. The Reports Are Prepared Only When Actual Changes Are Made Or Detected Whenever The Actual Group Management Occur. For That Purpose, The PSModule Uses An SQLite Statistics DataBase To Store Information About:</maml:para>
      <maml:para>- Events Related With Automatic Adding Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Automatic Removing Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Changes In Managed Groups Configuration That Might Affect The Group Membership, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With The Module Operation And Groups Management Intended To Be Provided To The Company IT's. The Internal Events Not Related With Specific Managed Group Are Not Kept In The Statistics DataBase. Therefore The Statistics DataBase Is Not Suitable Source Of Information About Troubleshooting Of Performance, Module Related Issues, And Script Related Issues. However It Is Perfectly Reliable Source Of Troubleshooting Information Related With Troubleshooting Of Incorrect Logic And Any Managed Groups Misconfiguration.</maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Only Prepares Reports And Reverts Them As "SnsReportCollection" Output Object. The Email Relay Options Differ From One Environment To Another, It Is Not Feasible To Maintain Multiple Settings Related With Email Sending In The Configuration DataBase, While Sending Of An Email From PowerShell Is Simple As Running Of A CmdLet. Depending On The Company, Might Be Used Different Languages, Different Wording, Company Branding, Company Stationaries, Company Colors And Company Visual Stylings In The Emails. From That Perspective The PSModule Reverts Reports In Custom Objects And Collections. The User Have To Convert Them To HTML Text And Send Them As Emails, Within The Automation Scripts Which Use "SnsPsAdGroupMembers" Module. The Simplest Way For Doing That Is Using "ConvertTo-Html" And "Send-MailMessage" Native PowerShell CmdLets. Whenever Managed Group Owners Are Not Interested To Receive Any Notifications The Reports For They Own Groups Can Be Disabled Via Leaving Empty The Notification Contacts Setting Of The Group (Or Remove All Notification Contacts For A Managed Group If There Are Already Specified). This Does Not Disable The Logging Of Events Into The Statistics DataBase.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>For DataBase Engine Is Used SQLite. SQLite Is Free Open Source Serverless DataBase, Which Comes With Its Own Advantages And Disadvantages. As Serverless DataBase There Is No Server To Manage The DataBase Requests And Locks. From That Perspective Using A Single SQLite DataBase Either Over Network Or Mapped Drives Or Simultaneously By Multiple Applications / PSSessions Might Lead To Errors In Accessing The DataBase Or DataBase Corruption.</maml:para>
      <maml:para>From That Perspective All The CmdLets Within This Module Have A Feature That Prevents Running Of Those CmdLets In Multiple PowerShell Sessions. All The CmdLets Have Parameter "Force" Which Allows The Usage Of The CmdLets In Multiple PSSessions, Use It At Your Own Risk. The Parameter Is Ignored And Does Not Work When The PSSession Is "As A Service" (In Automation Script Executed With Scheduled Task For Example).</maml:para>
      <maml:para>Both The Configuration And Statistics DataBases Are Located In "C:\ProgramData\SnsAdGroupMembers" By Default. In Order The Folder And DataBase Files To Be Created Properly, The First Run Of This CmdLet To Be Made In Elevated PowerShell Session. Creation Of The DataBase Folder And Setting The Required NTFS Permissions Requires Local Administrator Access Rights. The DataBase Files Can Be Moved / Migrated Into Different Folders, In That Case The Administrator Who Is Doing That Have To Make Sure That The Folder Exists, All The Users That Will Use This PSModule Will Have "Modify" NTFS Permissions Over The Folder And The DataBase Files, Move The DataBase Files Into The New Folder And Properly Provide The Module With The New Folder Absolute (Full) Path.</maml:para>
      <maml:para>Although Using This PSModule On Domain Controllers Is Possible, It Is Against The Best Practices And It Is Not Recommended. All Automations Shall Be Run On Dedicated Virtual Or Physical Machine. From That Perspective It Is Required "Local Admin" Access Rights.</maml:para>
      <maml:para>It Is Not Recommended The DataBase Files To Be Moved, And If That Happen They Shall Be Not Moved On Network Shares Or Mapped Drives. This Will Not Prevent The PSModule To Do Its Job. It Will Introduce Performance Degradation, Possible Interruption In Case Of Network Issues And Eventually Corruption Of The DataBases.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>Never Move DataBases Outside The Default Location When The PSModule Is Installed With Scope "CurrentUser".</maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>"CfgDbFolder" Setting Specifies The Location Of Both Configuration And Statistics DataBases Simultaneously Unless The Statistics DataBase Have Explicitly Specified Location. With Other Words When Modify Configuration DataBase Location And "StatDbFolder" Setting Is Not Used, Both DataBases Have To Be Moved In The New Location.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Contains CmdLets Intended To Be Run Interactively By The User And CmdLets Intended To Be Run Within Automation Scripts On A Schedule As A Service. The CmdLets Intended To Be Used Within Automation Scripts Comply With Additional Requirements Related With Logging, Reporting And Ability To Being Monitored (Using "SnsPsScriptsMonitoring" PSModule For Example). "Invoke-SnsAdGroupMembersManage" Is A CmdLet Intended To Be Used In An Automation Scripts. By Its Nature, This CmdLet Is An Automation Encapsulated Within A CmdLet. The Logs And Events Happening During The CmdLet Run Are Logged In An SQLite DataBase "GroupMembersProvStat.db" Referred Furter As Statistics DataBase. It Could Be Used For Other Reporting Purposes Like Periodical Comprehensive Reports About The Actions Taken By Automation Scripts (This Requires Additional Scripting To Read The DataBase And Prepare The Reports).</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>When Working With Active Directory It Is Important What Identity Attribute Will Be Chosen For Binding To The AD Objects. Although Naturally AD Uses DistinguishedName For Binding And LDAP Queries, It Is Not The Best Possible Identity. The DistinguishedName Is Unique But It Is Not Constant, It Can Be Changed Over The AD Object Life Cycle. An AD Object Can Be Renamed And / Or Moved Into Different Organizational Unit, Or The Organizational Unit Where The Object Is Located Can Be Renamed And / Or Moved. That Will Modify Object's Distinguished Name. In This Case The Active Directory Will Automatically Reflect Those Changes In The Attributes Of The Object And On All Relational Attributes Of The Remaining Objects Which Point To Our Object. For Example "member" Attribute Of All The Groups Where Our AD Object Is Member Of, Or "manager" Attribute Of All Accounts That Our User Is Manager. However AD Will Not Modify Accordingly The PSModule Configuration Stored In An External For The AD DataBase. This Will Lead To Errors And Failures.</maml:para>
      <maml:para>It Is Best Practice The AD Related Applications To Use For Binding Other Identity Attributes Which Do Not Change During The Objects Life Cycle. Those Are "objectGUID" And "objectSid". The Best Practices Gives Preference To The "objectSid" By Various Reasons. Since It Is Possible Groups To Have Member Objects Without "objectSid" (Contact Objects For Example) The "SnsPsAdGroupMembers" PSModule Uses As Identity The "ObjectGUID" Attribute. Thus Way When An Object Is Renamed Or Moved The PSModule Is Not Affected And Continue To Work As Intended.</maml:para>
      <maml:para>The The Well-Known AD Behavior, That When An Object Is Deleted And Then Recreated, All The Access Rights And Group Membership Are Lost, Is Related With The Fact That The Recreated Object Have Different "objectSid". Using The "objectGUID" As Identity Introduces Similar Behavior Of "SnsPsAdGroupMembers". Deletion And Recreation Of An AD Group Object Does Not Automatically Enable It For Automatic Members Management With The Logic Of The Deleted Group.</maml:para>
      <maml:para>The Using "objectGUID" As Identity In The PSModule Configuration Ensures That The PSModule Is Not Affected By Objects Rename Or Objects Move. When A Managed Group, Explicit Inclusion, Explicit Exclusion Is Renamed Or Moved Into Different OU, Their "objectGUID" Remains Intact. And The PSModule Continue To Bind To Those Objects Without Errors. However This Does Introduce Additional Overhead For The CmdLets Intended To Manage The Groups Configuration. When An Object Is Provided To Them They Need To Search For That Object In Active Directory, Enumerate The "objectGUID" Of The Object And Specify The Enumerated Value Into The Configuration DataBase. Since The CmdLets Query AD, That Query Can Be Made Against Multiple Attributes, Which Does Provide Freedom For The User To Use Multitude Of Values When An AD Object Is Provided To A Parameter. Please Refer To Each To The Parameters Sections Of Each CmdLet Help Document.</maml:para>
      <maml:para>When LDAP Queries Are Needed The Things Get More Complicated. The LDAP Queries Work Only With DistinguishedName. When You Need To Query About Reports Of A Person, Or Members Of A Group The AD Expects LDAP Query With DistinguishedName Values. An Example Of Often Use LDAP Query Clause Is:</maml:para>
      <maml:para>"(manager=CN=Jane Smith,CN=Users,DC=contoso,DC=com)"</maml:para>
      <maml:para>If "SnsPsAdGroupMembers" PSModule Keep It As Is Into The Configuration, In Case Of DistinguishedName Change, The Logic Will Revert No Results, Which Might Lead To Removal Of All The Members From The Group. Instead The LDAP Clause Is Stored Like:</maml:para>
      <maml:para>"(manager=00000000-0000-0000-0000-000000000000)"</maml:para>
      <maml:para>This Complicates The PSModule Further, As On The AD Managed Group Configuration Creation / Modification It Have To Evaluate The Specified Parameters, Match Them Using RegEx Pattern About Any Distinguished Names, Bind To The AD Object Using The Matched DistinguishedName, Enumerates The AD Object "objectGUID" And Amend The Matched DistinguishedName With The Enumerated "objectGUID". And Before The Actual AD Managed Group Members Management, It Have To Evaluate The Configuration About "objectGUID" Values Using RegEx Matching, Bind To The AD Object Using The Matched "objectGUID", Enumerate The AD Object DistinguishedName And Amend The "objectGUID" With The Enumerated DistinguishedName. Thus Way Introducing Overhead For The PSModule And For The Domain Controller Which Serves The LDAP Requests.</maml:para>
      <maml:para>To Reduce The Number Of The AD Requests And The Overhead, The PSModule Caches The Attributes Of The Previously Bind To Or Queried About AD Objects, And Consequently Uses The Cache Instead Of Making New AD Requests. The Effectiveness Of The AD Cache Depends On The Similarities In The Configuration Of The Groups.</maml:para>
      <maml:para>The Attributes Modified By The "SnsPsAdGroupMembers" PSModule Like "memberOf" AD Attribute, Are Never Cached. Caching Those Might Lead To False Positive Or Real Errors.</maml:para>
      <maml:para>The Values Of The AD Attributes Without Requirements For Uniqueness Cannot Be Used For Indexing And Searches In The Cache. For Example There Is No Uniqueness Requirement For "cn" Attribute, You Can Have Multiple Objects With The Same "cn" As Long As They Are Located In Different OU's. When A CmdLet Parameter From The PSModule Is Provided With "cn" Value, It Must Make LDAP Search To Enumerate The AD Object, Either To Confirm That The Value Corresponds To An AD Object Or To Throw Error About Multiple Objects. In Case We Have The Specified Value In The Cache It Is Not Certain That There Are No Other Objects With The Same Value In The AD Domain. Whenever We Use AD Attributes With Uniqueness Requirements Like Distinguished Name, For Example Presence Of The Provided Value In The Cache Can Be Safely Assumed As Correct And Unique, In That Case Query Against The AD Domain Is Not Needed. Usage Of Values In Attributes Without Uniqueness Requirements Reduces The Effectiveness Of The AD Cache Feature Further.</maml:para>
      <maml:para>Introducing A Cache In The PSModule Introduces All Generic Disadvantages Related With Caching, Like Cached Outdated Values. The "SnsPsAdGroupMembers" PSModule Keeps The AD Cache In The System Memory. This Does Ensure Maximum Speed For Accessing The Cache, With Negative Impact On The Machine Performance Because Of The Increased Memory Usage. Together With The Feature Which Does Not Allow Usage Of The PSModule In Multiple PSSession (Which Actually Force The Users To Close Their PSSessions Once They Finish Their Job), Ensures Relatively Short Life Span Of The Cached Entries, Thus Way Reducing The Cache Effectiveness But Increasing The Reliability Via Minimizing The Possibility For Issues Related With Outdated Entries.</maml:para>
      <maml:para>Although The Shorter Lifespan Of The Cached Entries Reduces The Possibility For Mistakes, It Does Not Eliminate Them Completely. Mistakes Might Happen Without Corrupted Or Outdated Cached Entry. Let Us Assume We Have A Department Related Group Where Members Are Added Based On Specific Value In The Department AD Attribute And Removed When The Value Is Different. At The Same Time, The Department AD Attribute Is Automatically Synchronized From The Company HR System. In Case Of Department Rebranding The Sync From The HR System Will Modify The Attribute Value Of All Department Members. In That Case All The Department Members Will Be Removed From The Group. This Is Addressed With Introducing Of New Feature Which Prevents Any Members Removal Whenever The Members Enumerated For Removing Are More Than Certain Threshold. The Threshold Is Configurable. The Default Value Is 50%.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" Provides A Feature Intended For Quick Identifying Whether A Group Is Automatically Managed Or Not, Which Is Disabled By Default. It Could Be Very Annoying And Frustrating To Manually Add Or Remove A Member Into A Group And The Automation To Revert The Changes Back Because The Member Does Not Match The Adding Or Match The Removing Criteria For The Automatic Group Members Management. Normally The IT Administrators Would Need To Check In The PS Module Configuration To Verify Whether An AD Group Is Automatically Managed Using The PSModule Before Membership Modification. This Might Lead To Failed Scheduled Tasks Due To Multiple PSSessions With The PSModule Loaded. From That Perspective "SnsPsAdGroupMembers" Stores A Predefined Constant Value In A Predefined AD Attribute Of The AD Managed Groups And Clears The Predefined Constant Value From The Predefined AD Attribute Of The Not Managed Groups. Therefore The Company IT Administrators Just Need To Look At That Attribute Before Manually Add Or Remove Groups Members In An AD Group.</maml:para>
      <maml:para>To Enable This Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet, To Specify An AD Attribute And A Constant Value Which Shall Be Set On The AD Managed Groups. To Disable That Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet To Clear Either The Value Or The AD Attribute Used By This Feature Or Both. When Enabled On A Scheduled Job After Actual Group Management "Invoke-SnsAdGroupMembersManage" Sets The Predefined Constant Value Into The Predefined AD Attribute Of All Enabled AD Managed Groups And Clears The Value From All Not Managed AD Groups. Therefore Once The Feature Is Disabled The User Have To Manually Clear The Value From The AD Attribute Of All The Groups In Case The Feature Was Ever Used. Changing The Attribute Will Not Clear The Value From The Old Attribute.</maml:para>
      <maml:para>NOTE: This Feature Considers As Managed Only The Groups That Are Enabled In The Groups Configuration. Disabling A Group From Automatic Members Management, Even Temporary Will Clear The AD Attribute Used By This Feature, Indicating To The Corporate IT Administrators, That The Group Membership Can Be Managed Manually.</maml:para>
      <maml:para>NOTE: This Feature Can Use Only AD Attributes With Type Of Single Valued String.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>Add-SnsAdManagedGroupContact Is Intended To Be Used Interactively By A User To Add New Notification Contact Into A Managed AD Group Entry In The Configuration DataBase. In The Process Any Existing Notification Contacts Remain Intact.</maml:para>
      <maml:para>NOTE: Please Make Sure That The PowerShell Is Closed, When You Finish With The Work On The Managed AD Groups Configuration. Otherwise Either The Other Users Or Any Automated Task Will Be Prevented From Work With The PSModule.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In Parameters Validations "Add-SnsAdManagedGroupContact" CmdLet Enumerates The AD Managed Group Objects Corresponding To The Specified Group Identities And Verifies The Specified Notification Contact Emails In Active Directory. Whenever An Email Exists It Is Amended With The PrimarySmtpAddress Of The AD Object, In Case The Email Does Not Exists In The AD No Errors Are Thrown Allowing Recipients From Other Domains And External For The Organization Recipients. In Case The User Specifies A Value Different Than SMTP Address And The CmdLet Cannot Enumerate The PrimarySmtpAddress Of The AD Object An Error Is Thrown.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "BeginProcessing" Method "Add-SnsAdManagedGroupContact" CmdLet Initializes The PSModule Configuration. Verifies The Existence, The Schema And The Integrity Of The Configuration DataBase. Verifies About Other PowerShell Processes Using "SnsPsAdGroupMembers" PSModule.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "ProcessRecord" Method "Add-SnsAdManagedGroupContact" CmdLet Loops Each Specified Group Entry And Add Each Specified Notification Contact To Each Group. Whenever A Specified Notification Contact Is Already Present In The AD Managed Group Configuration, A Warning Is Thrown. After The Adding Of All Notification Contacts To The Group Configuration, The Group Object Is Normalized And Verified, Then Sent To The Pipeline.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The CmdLet Reverts SnsAdManagedGroup Objects With The Following Properties And Methods:</maml:para>
      <maml:para>- "Position" Property Of Type Integer. Represents The Group Position In The Collection For Members Management.</maml:para>
      <maml:para>- "Identity" Property Of Type Guid. Represents The Managed Group AD "objectGUID".</maml:para>
      <maml:para>- "Name" Property Of Type String. Contains The Value Of The Managed Group "cn" Attribute.</maml:para>
      <maml:para>- "AddLogic" Property Of Type String. Contains The Logic For Adding Members Into The Managed Group.</maml:para>
      <maml:para>- "RemoveLogic" Property Of Type String. Contains The Logic For Removing Members From The Managed Group.</maml:para>
      <maml:para>- "Inclusions" Property Of Type SnsAdManagedGroupInclusion Array. Contains An Array With The Group's Explicit Inclusions. Each SnsAdManagedGroupInclusion Object Contains: "Identity" Property Of Type Guid. "Name" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Exclusions" Property Of Type SnsAdManagedGroupExclusion Array. Contains An Array With The Group's Explicit Exclusions. Each SnsAdManagedGroupExclusion Object Contains: "Identity" Property Of Type Guid. "Name" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Notify" Property Of Type SnsAdManagedGroupContact Array. Contains An Array With The Group's Notification Contacts. Each SnsAdManagedGroupContact Object Contains: "Email" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Enabled" Property Of Type Boolean. Represents Whether The Managed Group Entry Is Active Or Not.</maml:para>
      <maml:para>- "GetSnsRawAddLogic" Method Intended To Revert The Not Normalized Add Logic As It Is Set In The Group Configuration.</maml:para>
      <maml:para>- "GetSnsRawRemoveLogic" Method Intended To Revert The Not Normalized Remove Logic As It Is Set In The Group Configuration.</maml:para>
    </maml:description>
    <command:syntax>
      <!-- Parameter set: __AllParameterSets -->
      <command:syntaxItem>
        <maml:name>Add-SnsAdManagedGroupContact</maml:name>
        <!-- Parameter: Contact -->
        <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="NotificationContact,Email,Mail">
          <maml:name>Contact</maml:name>
          <maml:description>
            <maml:para>Specifies A Recipient For The Group Related Audit Reports.</maml:para>
            <maml:para></maml:para>
            <maml:para>The Parameter Accepts The Following Values:</maml:para>
            <maml:para>- SMTP Email Address. Can Be Used For External Recipients. Does Not Support Wildcard Characters.</maml:para>
            <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- distinguishedName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
            <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
            <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
            <maml:para></maml:para>
            <maml:para>In Case Multiple Values Are Specified All Specified Contacts Will Be Added To The Specified Group.</maml:para>
            <maml:para>In Case Multiple Values Are Specified And Multiple Managed AD Groups Are Specified, All Specified Contacts Will Be Added To All Specified Groups.</maml:para>
          </maml:description>
          <command:parameterValue required="true">object</command:parameterValue>
          <dev:type>
            <maml:name>System.Object</maml:name>
            <maml:uri />
          </dev:type>
        </command:parameter>
        <!-- Parameter: Identity -->
        <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
          <maml:name>Identity</maml:name>
          <maml:description>
            <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
            <maml:para></maml:para>
            <maml:para>The Parameter Accepts The Following Values:</maml:para>
            <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
            <maml:para>- objectGUID</maml:para>
            <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
            <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
            <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
            <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
            <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
            <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
            <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
          </maml:description>
          <command:parameterValue required="true">object</command:parameterValue>
          <dev:type>
            <maml:name>System.Object</maml:name>
            <maml:uri />
          </dev:type>
        </command:parameter>
        <!-- Parameter: DomainController -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>DomainController</maml:name>
          <maml:description>
            <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
            <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
            <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
            <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
            <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
        <!-- Parameter: Force -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>Force</maml:name>
          <maml:description>
            <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
    <command:parameters>
      <!-- Parameter: Identity -->
      <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
        <maml:name>Identity</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
          <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
          <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
        <maml:name>Group</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
          <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
          <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
          <maml:para>This is an alias of the Identity parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
        <maml:name>ManagedGroup</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
          <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
          <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
          <maml:para>This is an alias of the Identity parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <!-- Parameter: Contact -->
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="NotificationContact,Email,Mail">
        <maml:name>Contact</maml:name>
        <maml:description>
          <maml:para>Specifies A Recipient For The Group Related Audit Reports.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Can Be Used For External Recipients. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- distinguishedName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Contacts Will Be Added To The Specified Group.</maml:para>
          <maml:para>In Case Multiple Values Are Specified And Multiple Managed AD Groups Are Specified, All Specified Contacts Will Be Added To All Specified Groups.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="NotificationContact,Email,Mail">
        <maml:name>NotificationContact</maml:name>
        <maml:description>
          <maml:para>Specifies A Recipient For The Group Related Audit Reports.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Can Be Used For External Recipients. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- distinguishedName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Contacts Will Be Added To The Specified Group.</maml:para>
          <maml:para>In Case Multiple Values Are Specified And Multiple Managed AD Groups Are Specified, All Specified Contacts Will Be Added To All Specified Groups.</maml:para>
          <maml:para>This is an alias of the Contact parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="NotificationContact,Email,Mail">
        <maml:name>Email</maml:name>
        <maml:description>
          <maml:para>Specifies A Recipient For The Group Related Audit Reports.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Can Be Used For External Recipients. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- distinguishedName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Contacts Will Be Added To The Specified Group.</maml:para>
          <maml:para>In Case Multiple Values Are Specified And Multiple Managed AD Groups Are Specified, All Specified Contacts Will Be Added To All Specified Groups.</maml:para>
          <maml:para>This is an alias of the Contact parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="NotificationContact,Email,Mail">
        <maml:name>Mail</maml:name>
        <maml:description>
          <maml:para>Specifies A Recipient For The Group Related Audit Reports.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address. Can Be Used For External Recipients. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- distinguishedName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Contacts Will Be Added To The Specified Group.</maml:para>
          <maml:para>In Case Multiple Values Are Specified And Multiple Managed AD Groups Are Specified, All Specified Contacts Will Be Added To All Specified Groups.</maml:para>
          <maml:para>This is an alias of the Contact parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <!-- Parameter: DomainController -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>DomainController</maml:name>
        <maml:description>
          <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
          <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
          <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
          <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
          <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: Force -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>Force</maml:name>
        <maml:description>
          <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
        </maml:description>
        <command:parameterValue required="true">SwitchParameter</command:parameterValue>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
    </command:parameters>
    <command:inputTypes>
      <command:inputType>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
          <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
          <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
        </maml:description>
      </command:inputType>
    </command:inputTypes>
    <command:returnValues>
      <!-- OutputType: SnsAdManagedGroup -->
      <command:returnValue>
        <dev:type>
          <maml:name>SnsAdGroupMembers.SnsAdManagedGroup</maml:name>
          <maml:uri />
        </dev:type>
      </command:returnValue>
    </command:returnValues>
    <maml:alertSet>
      <maml:title></maml:title>
      <maml:alert>
        <maml:para>AUTHOR: Svetoslav Nedyalkov Savov</maml:para>
        <maml:para>THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK</maml:para>
        <maml:para>OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.</maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
      </maml:alert>
    </maml:alertSet>
    <command:examples>
      <command:example>
        <maml:title>---------- EXAMPLE 1 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Add-SnsAdManagedGroupContact -Identity "Finance Department DL" `
-Contact "John Smith" -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Enumerates John Smith's PrimarySmtpAddress From AD And Add The Address As Notification Contact For AD Managed Group "Finance Department DL".</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 2 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Add-SnsAdManagedGroupContact -Identity "Finance Department DL" `
-Contact "John Smith", "john.smith@outlook.com" -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Enumerates John Smith's PrimarySmtpAddress From AD, "john.smith@outlook.com" Address Remains Unverified, And Add Both Addresses As Notification Contacts For AD Managed Group "Finance Department DL". Thus way John Smith Will Receive Notifications Both In His Corporate And Private Mailbox. Not Saying It Is A Good And Secure Practice, It Is Just Demonstration That It Is Doable, And How Can Be Done.</maml:para>
          <maml:para>When Users From Other AD Domains In Multi Domain Forest Have To Be Added As Notification Contacts, Must Be Used Their Email Address. The CmdLet Will Not Be Able To Enumerate Their Accounts Outside Of The Current Domain.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 3 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Add-SnsAdManagedGroupContact -Identity "*Finance*" `
-Contact "John Smith";</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Enumerates The Configuration Object For AD Managed Group "Finance Department" And Add "John Smith" As A Notification Contact. In Case The Wildcard Value Matches More Than One AD Managed Group A Terminating Error Will Be Thrown And The Request Will Be Not Completed.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 4 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Get-SnsAdManagedGroup "*Finance*";</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Enumerates The Configuration Objects For AD Managed Groups That Match The Wildcard Pattern.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
          <maml:para>$arrGrs;</maml:para>
          <maml:para></maml:para>
          <maml:para>Lists On The Host Window The Enumerated AD Managed Groups.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
          <maml:para>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = $arrGrs | Add-SnsAdManagedGroupContact -Contact "John Smith";</maml:para>
          <maml:para></maml:para>
          <maml:para>Adds "John Smith" As Notification Contact For All The AD Managed Groups Sent Via The Pipeline. Use This If You Really Desperately Need To Workaround The Errors From The Previous Example. To List And Verify The Groups That Are Sent Via The Pipeline Before Executing The CmdLet Is More Than A Good Idea. There Are No Errors In This Scenario Because Multiple Values Are Sent, Instead Of Specifying Single Value That Matches Multiple Objects. With Other Words There Is One To One Relation Between The Provided And Processed Objects.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
    </command:examples>
    <maml:relatedLinks>
      <maml:navigationLink>
        <maml:linkText> svesavov / SnsPsAdGroupMembers - </maml:linkText>
        <maml:uri>https://github.com/svesavov/SnsPsAdGroupMembers</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> PowerShell Gallery - </maml:linkText>
        <maml:uri>https://www.powershellgallery.com/packages/SnsPsAdGroupMembers/</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> Svetoslav Savov on LinkedIn - </maml:linkText>
        <maml:uri>https://www.linkedin.com/in/svetoslavsavov</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> SQLite V3 - </maml:linkText>
        <maml:uri>https://sqlite.org/index.html</maml:uri>
      </maml:navigationLink>
    </maml:relatedLinks>
  </command:command>
  <!-- Cmdlet: Clear-SnsAdManagedGroupContact -->
  <command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
    <command:details>
      <command:name>Clear-SnsAdManagedGroupContact</command:name>
      <command:verb>Clear</command:verb>
      <command:noun>SnsAdManagedGroupContact</command:noun>
      <maml:description>
        <maml:para>Removes All Notification Contacts Associated With A Managed Active Directory Group.</maml:para>
      </maml:description>
    </command:details>
    <maml:description>
      <maml:para>Removes All Notification Contacts Associated With A Managed Active Directory Group.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Operation Of "SnsPsAdGroupMembers" PSModule Install It With "AllUsers" Scope. The Idea Behind This Module Is To Be Used On A Scheduled Task "As Service" For The Actual Group Members Management, And Interactively By IT Administrators To Create And Modify The Managed Groups Configuration. This Requires The PSModule To Be Available To Multiple User Accounts.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Creation Of "SnsPsAdGroupMembers" PSModule DataBases, The First Load Of The PSModule Must Be In Elevated Mode. In The Normal Operation The PSModule Does Not Require Elevated Mode. More Information About That Is Provided Further In This Document.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"Why Should I Use This PSModule Instead Of Dynamic Groups?":</maml:para>
      <maml:para>- Well First And Foremost Reason Is Related With The Fact That This PowerShell Module Does Allow To Have Different Logic For Adding And Removing Members. This Is Not Achievable With Dynamic Groups.</maml:para>
      <maml:para>- The Company IT Department Might Need To Use A Single Group For Granting Access Rights In On Premises AD, AzureAD And Use It As Distribution List At The Same Time. Although This Can Be Achieved With Dynamic Groups You Have To Maintain At Least Two Of Them, One For On Premises AD And One For AzureAD.</maml:para>
      <maml:para>- There Are Cases Related With Certain AzureAD Functionalities And Synchronizations With Third Party Cloud Solutions Which Do Not Support Nested And Dynamic Groups. Managing Of Groups With Large Number Of Members In Corporate Environment Without Using Of Group Nestling Could Be Quite Tricky And Related With Lot Of Users Frustration And Administrative Effort.</maml:para>
      <maml:para>- The "SnsPsAdGroupMembers" PSModule Prepare Reports About Modifying Group Members And Audit Of Changes In The Group Management Settings. Whenever A Group Is Used For Granting Sensitive Access Rights Or Managing The Members Of A Sensitive Distribution List, The Group Owners Might Want To Receive Those Reports, Often Immediately After The Above-Mentioned Actions Are Taken.</maml:para>
      <maml:para>- The PSModule Can Be Used Only For Adding Or Only For Removing Members. Using Of Both Is Not Mandatory. This Does Allow Implementation Of Process For Adding Members In Sensitive Groups, Like "Domain Admins" For Example, Following Formal Approval Process, But Removing Members Immediately When The Person Who Owns The Account Leave The Company, Or Change The Position. In This Case There Will Be Zero Tolerance For Users "Forgotten" With More Than Needed Access Rights.</maml:para>
      <maml:para>This PSModule Have The Same Disadvantages And Requirements As The Dynamic Groups. Since The Management Logic Is Based On AD Attribute Values, It Requires The Used Ones To Be Up To Date And Consistent. Some Sort Of Synchronization From The Company HR System Would Address This. Such A Synchronization Is Nice To Have But Not A Requirement. Using My Other PSModule's Will Be Relatively Easy Creation Of Own Synchronization Related With Any On Premises HR Application. Most Of The Cloud Based Ones, Already Have Out Of The Box Synchronization Tools. Creation Of New One Would Not Be Feasible, But It Depends On The API's The Tool Provides.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Manages The Membership Of Active Directory Groups In A Single Domain Forest Based On Predefined Logic About Adding And Removing Members. For That Purpose, The PowerShell Module Uses SQLite Configuration DataBase To Keep Information About:</maml:para>
      <maml:para>- The Managed Groups.</maml:para>
      <maml:para>- The Logic For Adding Members Into Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- The Logic For Removing Members From Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- Explicit Group Inclusions. Those Are AD Objects Which Shall Be Added As Group Members, Although They Do Not Meet The Adding Criteria.</maml:para>
      <maml:para>- Explicit Group Exclusions. Those Are AD Objects Which Shall Not Be Added As Group Members, Although They Do Meet The Adding Criteria.</maml:para>
      <maml:para>- Notification Contacts Who Shall Receive Reports About The Actions And Audit Events Related With Their Own Groups.</maml:para>
      <maml:para>- The PSModule Configuration.</maml:para>
      <maml:para>- Managed Groups Configuration Changes Tracking.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Uses Another SQLite DataBase To Store All The Events Related With The CmdLets Operation And Events Related With Actions Taken On The Managed Groups.</maml:para>
      <maml:para></maml:para>
      <maml:para>To Increase The Confidence In The Automation Among The Group Owners, "SnsPsAdGroupMembers" PSModule Produces Reports Intended To Be Provided To Those Owners, Whenever The PSModule Adds And / Or Removes Members, Whenever It Detects Changes In The Groups Configuration That Might Affect The Group Members, Such Like Changes In The Add Logic, Remove Logic, Explicit Inclusions, Explicit Exclusions And Notification Contacts.</maml:para>
      <maml:para>In Case Of Changes In The Notification Contacts, Both The Old And New Contacts Are Included In The Report Recipients List. The Reports Are Prepared Only When Actual Changes Are Made Or Detected Whenever The Actual Group Management Occur. For That Purpose, The PSModule Uses An SQLite Statistics DataBase To Store Information About:</maml:para>
      <maml:para>- Events Related With Automatic Adding Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Automatic Removing Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Changes In Managed Groups Configuration That Might Affect The Group Membership, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With The Module Operation And Groups Management Intended To Be Provided To The Company IT's. The Internal Events Not Related With Specific Managed Group Are Not Kept In The Statistics DataBase. Therefore The Statistics DataBase Is Not Suitable Source Of Information About Troubleshooting Of Performance, Module Related Issues, And Script Related Issues. However It Is Perfectly Reliable Source Of Troubleshooting Information Related With Troubleshooting Of Incorrect Logic And Any Managed Groups Misconfiguration.</maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Only Prepares Reports And Reverts Them As "SnsReportCollection" Output Object. The Email Relay Options Differ From One Environment To Another, It Is Not Feasible To Maintain Multiple Settings Related With Email Sending In The Configuration DataBase, While Sending Of An Email From PowerShell Is Simple As Running Of A CmdLet. Depending On The Company, Might Be Used Different Languages, Different Wording, Company Branding, Company Stationaries, Company Colors And Company Visual Stylings In The Emails. From That Perspective The PSModule Reverts Reports In Custom Objects And Collections. The User Have To Convert Them To HTML Text And Send Them As Emails, Within The Automation Scripts Which Use "SnsPsAdGroupMembers" Module. The Simplest Way For Doing That Is Using "ConvertTo-Html" And "Send-MailMessage" Native PowerShell CmdLets. Whenever Managed Group Owners Are Not Interested To Receive Any Notifications The Reports For They Own Groups Can Be Disabled Via Leaving Empty The Notification Contacts Setting Of The Group (Or Remove All Notification Contacts For A Managed Group If There Are Already Specified). This Does Not Disable The Logging Of Events Into The Statistics DataBase.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>For DataBase Engine Is Used SQLite. SQLite Is Free Open Source Serverless DataBase, Which Comes With Its Own Advantages And Disadvantages. As Serverless DataBase There Is No Server To Manage The DataBase Requests And Locks. From That Perspective Using A Single SQLite DataBase Either Over Network Or Mapped Drives Or Simultaneously By Multiple Applications / PSSessions Might Lead To Errors In Accessing The DataBase Or DataBase Corruption.</maml:para>
      <maml:para>From That Perspective All The CmdLets Within This Module Have A Feature That Prevents Running Of Those CmdLets In Multiple PowerShell Sessions. All The CmdLets Have Parameter "Force" Which Allows The Usage Of The CmdLets In Multiple PSSessions, Use It At Your Own Risk. The Parameter Is Ignored And Does Not Work When The PSSession Is "As A Service" (In Automation Script Executed With Scheduled Task For Example).</maml:para>
      <maml:para>Both The Configuration And Statistics DataBases Are Located In "C:\ProgramData\SnsAdGroupMembers" By Default. In Order The Folder And DataBase Files To Be Created Properly, The First Run Of This CmdLet To Be Made In Elevated PowerShell Session. Creation Of The DataBase Folder And Setting The Required NTFS Permissions Requires Local Administrator Access Rights. The DataBase Files Can Be Moved / Migrated Into Different Folders, In That Case The Administrator Who Is Doing That Have To Make Sure That The Folder Exists, All The Users That Will Use This PSModule Will Have "Modify" NTFS Permissions Over The Folder And The DataBase Files, Move The DataBase Files Into The New Folder And Properly Provide The Module With The New Folder Absolute (Full) Path.</maml:para>
      <maml:para>Although Using This PSModule On Domain Controllers Is Possible, It Is Against The Best Practices And It Is Not Recommended. All Automations Shall Be Run On Dedicated Virtual Or Physical Machine. From That Perspective It Is Required "Local Admin" Access Rights.</maml:para>
      <maml:para>It Is Not Recommended The DataBase Files To Be Moved, And If That Happen They Shall Be Not Moved On Network Shares Or Mapped Drives. This Will Not Prevent The PSModule To Do Its Job. It Will Introduce Performance Degradation, Possible Interruption In Case Of Network Issues And Eventually Corruption Of The DataBases.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>Never Move DataBases Outside The Default Location When The PSModule Is Installed With Scope "CurrentUser".</maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>"CfgDbFolder" Setting Specifies The Location Of Both Configuration And Statistics DataBases Simultaneously Unless The Statistics DataBase Have Explicitly Specified Location. With Other Words When Modify Configuration DataBase Location And "StatDbFolder" Setting Is Not Used, Both DataBases Have To Be Moved In The New Location.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Contains CmdLets Intended To Be Run Interactively By The User And CmdLets Intended To Be Run Within Automation Scripts On A Schedule As A Service. The CmdLets Intended To Be Used Within Automation Scripts Comply With Additional Requirements Related With Logging, Reporting And Ability To Being Monitored (Using "SnsPsScriptsMonitoring" PSModule For Example). "Invoke-SnsAdGroupMembersManage" Is A CmdLet Intended To Be Used In An Automation Scripts. By Its Nature, This CmdLet Is An Automation Encapsulated Within A CmdLet. The Logs And Events Happening During The CmdLet Run Are Logged In An SQLite DataBase "GroupMembersProvStat.db" Referred Furter As Statistics DataBase. It Could Be Used For Other Reporting Purposes Like Periodical Comprehensive Reports About The Actions Taken By Automation Scripts (This Requires Additional Scripting To Read The DataBase And Prepare The Reports).</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>When Working With Active Directory It Is Important What Identity Attribute Will Be Chosen For Binding To The AD Objects. Although Naturally AD Uses DistinguishedName For Binding And LDAP Queries, It Is Not The Best Possible Identity. The DistinguishedName Is Unique But It Is Not Constant, It Can Be Changed Over The AD Object Life Cycle. An AD Object Can Be Renamed And / Or Moved Into Different Organizational Unit, Or The Organizational Unit Where The Object Is Located Can Be Renamed And / Or Moved. That Will Modify Object's Distinguished Name. In This Case The Active Directory Will Automatically Reflect Those Changes In The Attributes Of The Object And On All Relational Attributes Of The Remaining Objects Which Point To Our Object. For Example "member" Attribute Of All The Groups Where Our AD Object Is Member Of, Or "manager" Attribute Of All Accounts That Our User Is Manager. However AD Will Not Modify Accordingly The PSModule Configuration Stored In An External For The AD DataBase. This Will Lead To Errors And Failures.</maml:para>
      <maml:para>It Is Best Practice The AD Related Applications To Use For Binding Other Identity Attributes Which Do Not Change During The Objects Life Cycle. Those Are "objectGUID" And "objectSid". The Best Practices Gives Preference To The "objectSid" By Various Reasons. Since It Is Possible Groups To Have Member Objects Without "objectSid" (Contact Objects For Example) The "SnsPsAdGroupMembers" PSModule Uses As Identity The "ObjectGUID" Attribute. Thus Way When An Object Is Renamed Or Moved The PSModule Is Not Affected And Continue To Work As Intended.</maml:para>
      <maml:para>The The Well-Known AD Behavior, That When An Object Is Deleted And Then Recreated, All The Access Rights And Group Membership Are Lost, Is Related With The Fact That The Recreated Object Have Different "objectSid". Using The "objectGUID" As Identity Introduces Similar Behavior Of "SnsPsAdGroupMembers". Deletion And Recreation Of An AD Group Object Does Not Automatically Enable It For Automatic Members Management With The Logic Of The Deleted Group.</maml:para>
      <maml:para>The Using "objectGUID" As Identity In The PSModule Configuration Ensures That The PSModule Is Not Affected By Objects Rename Or Objects Move. When A Managed Group, Explicit Inclusion, Explicit Exclusion Is Renamed Or Moved Into Different OU, Their "objectGUID" Remains Intact. And The PSModule Continue To Bind To Those Objects Without Errors. However This Does Introduce Additional Overhead For The CmdLets Intended To Manage The Groups Configuration. When An Object Is Provided To Them They Need To Search For That Object In Active Directory, Enumerate The "objectGUID" Of The Object And Specify The Enumerated Value Into The Configuration DataBase. Since The CmdLets Query AD, That Query Can Be Made Against Multiple Attributes, Which Does Provide Freedom For The User To Use Multitude Of Values When An AD Object Is Provided To A Parameter. Please Refer To Each To The Parameters Sections Of Each CmdLet Help Document.</maml:para>
      <maml:para>When LDAP Queries Are Needed The Things Get More Complicated. The LDAP Queries Work Only With DistinguishedName. When You Need To Query About Reports Of A Person, Or Members Of A Group The AD Expects LDAP Query With DistinguishedName Values. An Example Of Often Use LDAP Query Clause Is:</maml:para>
      <maml:para>"(manager=CN=Jane Smith,CN=Users,DC=contoso,DC=com)"</maml:para>
      <maml:para>If "SnsPsAdGroupMembers" PSModule Keep It As Is Into The Configuration, In Case Of DistinguishedName Change, The Logic Will Revert No Results, Which Might Lead To Removal Of All The Members From The Group. Instead The LDAP Clause Is Stored Like:</maml:para>
      <maml:para>"(manager=00000000-0000-0000-0000-000000000000)"</maml:para>
      <maml:para>This Complicates The PSModule Further, As On The AD Managed Group Configuration Creation / Modification It Have To Evaluate The Specified Parameters, Match Them Using RegEx Pattern About Any Distinguished Names, Bind To The AD Object Using The Matched DistinguishedName, Enumerates The AD Object "objectGUID" And Amend The Matched DistinguishedName With The Enumerated "objectGUID". And Before The Actual AD Managed Group Members Management, It Have To Evaluate The Configuration About "objectGUID" Values Using RegEx Matching, Bind To The AD Object Using The Matched "objectGUID", Enumerate The AD Object DistinguishedName And Amend The "objectGUID" With The Enumerated DistinguishedName. Thus Way Introducing Overhead For The PSModule And For The Domain Controller Which Serves The LDAP Requests.</maml:para>
      <maml:para>To Reduce The Number Of The AD Requests And The Overhead, The PSModule Caches The Attributes Of The Previously Bind To Or Queried About AD Objects, And Consequently Uses The Cache Instead Of Making New AD Requests. The Effectiveness Of The AD Cache Depends On The Similarities In The Configuration Of The Groups.</maml:para>
      <maml:para>The Attributes Modified By The "SnsPsAdGroupMembers" PSModule Like "memberOf" AD Attribute, Are Never Cached. Caching Those Might Lead To False Positive Or Real Errors.</maml:para>
      <maml:para>The Values Of The AD Attributes Without Requirements For Uniqueness Cannot Be Used For Indexing And Searches In The Cache. For Example There Is No Uniqueness Requirement For "cn" Attribute, You Can Have Multiple Objects With The Same "cn" As Long As They Are Located In Different OU's. When A CmdLet Parameter From The PSModule Is Provided With "cn" Value, It Must Make LDAP Search To Enumerate The AD Object, Either To Confirm That The Value Corresponds To An AD Object Or To Throw Error About Multiple Objects. In Case We Have The Specified Value In The Cache It Is Not Certain That There Are No Other Objects With The Same Value In The AD Domain. Whenever We Use AD Attributes With Uniqueness Requirements Like Distinguished Name, For Example Presence Of The Provided Value In The Cache Can Be Safely Assumed As Correct And Unique, In That Case Query Against The AD Domain Is Not Needed. Usage Of Values In Attributes Without Uniqueness Requirements Reduces The Effectiveness Of The AD Cache Feature Further.</maml:para>
      <maml:para>Introducing A Cache In The PSModule Introduces All Generic Disadvantages Related With Caching, Like Cached Outdated Values. The "SnsPsAdGroupMembers" PSModule Keeps The AD Cache In The System Memory. This Does Ensure Maximum Speed For Accessing The Cache, With Negative Impact On The Machine Performance Because Of The Increased Memory Usage. Together With The Feature Which Does Not Allow Usage Of The PSModule In Multiple PSSession (Which Actually Force The Users To Close Their PSSessions Once They Finish Their Job), Ensures Relatively Short Life Span Of The Cached Entries, Thus Way Reducing The Cache Effectiveness But Increasing The Reliability Via Minimizing The Possibility For Issues Related With Outdated Entries.</maml:para>
      <maml:para>Although The Shorter Lifespan Of The Cached Entries Reduces The Possibility For Mistakes, It Does Not Eliminate Them Completely. Mistakes Might Happen Without Corrupted Or Outdated Cached Entry. Let Us Assume We Have A Department Related Group Where Members Are Added Based On Specific Value In The Department AD Attribute And Removed When The Value Is Different. At The Same Time, The Department AD Attribute Is Automatically Synchronized From The Company HR System. In Case Of Department Rebranding The Sync From The HR System Will Modify The Attribute Value Of All Department Members. In That Case All The Department Members Will Be Removed From The Group. This Is Addressed With Introducing Of New Feature Which Prevents Any Members Removal Whenever The Members Enumerated For Removing Are More Than Certain Threshold. The Threshold Is Configurable. The Default Value Is 50%.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" Provides A Feature Intended For Quick Identifying Whether A Group Is Automatically Managed Or Not, Which Is Disabled By Default. It Could Be Very Annoying And Frustrating To Manually Add Or Remove A Member Into A Group And The Automation To Revert The Changes Back Because The Member Does Not Match The Adding Or Match The Removing Criteria For The Automatic Group Members Management. Normally The IT Administrators Would Need To Check In The PS Module Configuration To Verify Whether An AD Group Is Automatically Managed Using The PSModule Before Membership Modification. This Might Lead To Failed Scheduled Tasks Due To Multiple PSSessions With The PSModule Loaded. From That Perspective "SnsPsAdGroupMembers" Stores A Predefined Constant Value In A Predefined AD Attribute Of The AD Managed Groups And Clears The Predefined Constant Value From The Predefined AD Attribute Of The Not Managed Groups. Therefore The Company IT Administrators Just Need To Look At That Attribute Before Manually Add Or Remove Groups Members In An AD Group.</maml:para>
      <maml:para>To Enable This Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet, To Specify An AD Attribute And A Constant Value Which Shall Be Set On The AD Managed Groups. To Disable That Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet To Clear Either The Value Or The AD Attribute Used By This Feature Or Both. When Enabled On A Scheduled Job After Actual Group Management "Invoke-SnsAdGroupMembersManage" Sets The Predefined Constant Value Into The Predefined AD Attribute Of All Enabled AD Managed Groups And Clears The Value From All Not Managed AD Groups. Therefore Once The Feature Is Disabled The User Have To Manually Clear The Value From The AD Attribute Of All The Groups In Case The Feature Was Ever Used. Changing The Attribute Will Not Clear The Value From The Old Attribute.</maml:para>
      <maml:para>NOTE: This Feature Considers As Managed Only The Groups That Are Enabled In The Groups Configuration. Disabling A Group From Automatic Members Management, Even Temporary Will Clear The AD Attribute Used By This Feature, Indicating To The Corporate IT Administrators, That The Group Membership Can Be Managed Manually.</maml:para>
      <maml:para>NOTE: This Feature Can Use Only AD Attributes With Type Of Single Valued String.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>Clear-SnsAdManagedGroupContact Is Intended To Be Used Interactively By A User To Remove All Notification Contacts Of A Managed AD Group Entry In The Configuration DataBase.</maml:para>
      <maml:para>NOTE: Please Make Sure That The PowerShell Is Closed, When You Finish With The Work On The Managed AD Groups Configuration. Otherwise Either The Other Users Or Any Automated Task Will Be Prevented From Work With The PSModule.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In Parameters Validations "Clear-SnsAdManagedGroupContact" CmdLet Enumerates The AD Managed Group Objects Corresponding To The Specified Group Identities.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "BeginProcessing" Method "Clear-SnsAdManagedGroupContact" CmdLet Initializes The PSModule Configuration. Verifies The Existence, The Schema And The Integrity Of The Configuration DataBase. Verifies About Other PowerShell Processes Using "SnsPsAdGroupMembers" PSModule.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "ProcessRecord" Method "Clear-SnsAdManagedGroupContact" CmdLet Loops Each Specified Group Entry And Remove All Notification Contacts Of Each Group. Whenever A Specified AD Managed Group Have No Notification Contacts, A Warning Is Thrown. After The Removing Of All Notification Contacts From The Group Configuration, The Group Object Is Normalized And Verified, Then Sent To The Pipeline.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The CmdLet Reverts SnsAdManagedGroup Objects With The Following Properties And Methods:</maml:para>
      <maml:para>- "Position" Property Of Type Integer. Represents The Group Position In The Collection For Members Management.</maml:para>
      <maml:para>- "Identity" Property Of Type Guid. Represents The Managed Group AD "objectGUID".</maml:para>
      <maml:para>- "Name" Property Of Type String. Contains The Value Of The Managed Group "cn" Attribute.</maml:para>
      <maml:para>- "AddLogic" Property Of Type String. Contains The Logic For Adding Members Into The Managed Group.</maml:para>
      <maml:para>- "RemoveLogic" Property Of Type String. Contains The Logic For Removing Members From The Managed Group.</maml:para>
      <maml:para>- "Inclusions" Property Of Type SnsAdManagedGroupInclusion Array. Contains An Array With The Group's Explicit Inclusions. Each SnsAdManagedGroupInclusion Object Contains: "Identity" Property Of Type Guid. "Name" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Exclusions" Property Of Type SnsAdManagedGroupExclusion Array. Contains An Array With The Group's Explicit Exclusions. Each SnsAdManagedGroupExclusion Object Contains: "Identity" Property Of Type Guid. "Name" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Notify" Property Of Type SnsAdManagedGroupContact Array. Contains An Array With The Group's Notification Contacts. Each SnsAdManagedGroupContact Object Contains: "Email" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Enabled" Property Of Type Boolean. Represents Whether The Managed Group Entry Is Active Or Not.</maml:para>
      <maml:para>- "GetSnsRawAddLogic" Method Intended To Revert The Not Normalized Add Logic As It Is Set In The Group Configuration.</maml:para>
      <maml:para>- "GetSnsRawRemoveLogic" Method Intended To Revert The Not Normalized Remove Logic As It Is Set In The Group Configuration.</maml:para>
    </maml:description>
    <command:syntax>
      <!-- Parameter set: __AllParameterSets -->
      <command:syntaxItem>
        <maml:name>Clear-SnsAdManagedGroupContact</maml:name>
        <!-- Parameter: Identity -->
        <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
          <maml:name>Identity</maml:name>
          <maml:description>
            <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
            <maml:para></maml:para>
            <maml:para>The Parameter Accepts The Following Values:</maml:para>
            <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
            <maml:para>- objectGUID</maml:para>
            <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
            <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
            <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
            <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
            <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
            <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
            <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
          </maml:description>
          <command:parameterValue required="true">object</command:parameterValue>
          <dev:type>
            <maml:name>System.Object</maml:name>
            <maml:uri />
          </dev:type>
        </command:parameter>
        <!-- Parameter: DomainController -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>DomainController</maml:name>
          <maml:description>
            <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
            <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
            <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
            <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
            <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
        <!-- Parameter: Force -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>Force</maml:name>
          <maml:description>
            <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
    <command:parameters>
      <!-- Parameter: Identity -->
      <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
        <maml:name>Identity</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
          <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
          <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
        <maml:name>Group</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
          <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
          <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
          <maml:para>This is an alias of the Identity parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
        <maml:name>ManagedGroup</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
          <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
          <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
          <maml:para>This is an alias of the Identity parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <!-- Parameter: DomainController -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>DomainController</maml:name>
        <maml:description>
          <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
          <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
          <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
          <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
          <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: Force -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>Force</maml:name>
        <maml:description>
          <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
        </maml:description>
        <command:parameterValue required="true">SwitchParameter</command:parameterValue>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
    </command:parameters>
    <command:inputTypes>
      <command:inputType>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
          <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
          <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
        </maml:description>
      </command:inputType>
    </command:inputTypes>
    <command:returnValues>
      <!-- OutputType: SnsAdManagedGroup -->
      <command:returnValue>
        <dev:type>
          <maml:name>SnsAdGroupMembers.SnsAdManagedGroup</maml:name>
          <maml:uri />
        </dev:type>
      </command:returnValue>
    </command:returnValues>
    <maml:alertSet>
      <maml:title></maml:title>
      <maml:alert>
        <maml:para>AUTHOR: Svetoslav Nedyalkov Savov</maml:para>
        <maml:para>THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK</maml:para>
        <maml:para>OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.</maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
      </maml:alert>
    </maml:alertSet>
    <command:examples>
      <command:example>
        <maml:title>---------- EXAMPLE 1 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Clear-SnsAdManagedGroupContact -Identity "Finance Department";</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Removes All Notification Contacts Of AD Managed Group "Finance Department".</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 2 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Clear-SnsAdManagedGroupContact -Identity "*Finance*";</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Enumerates The Configuration Object For AD Managed Group "Finance Department" And Remove All Notification Contacts Associated With It. In Case The Wildcard Value Matches More Than One AD Managed Group A Terminating Error Will Be Thrown And The Request Will Be Not Completed.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 3 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Get-SnsAdManagedGroup "*Finance*";</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Enumerates The Configuration Objects For AD Managed Groups That Match The Wildcard Pattern.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
          <maml:para>$arrGrs;</maml:para>
          <maml:para></maml:para>
          <maml:para>Lists On The Host Window The Enumerated AD Managed Groups.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
          <maml:para>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = $arrGrs | Clear-SnsAdManagedGroupContact;</maml:para>
          <maml:para></maml:para>
          <maml:para>Removes All Notification Contacts Of All Sent Via The Pipeline AD Managed Groups. Use This If You Really Desperately Need To Workaround The Errors From The Previous Example. To List And Verify The Groups That Are Sent Via The Pipeline Before Executing The CmdLet Is More Than A Good Idea. There Are No Errors In This Scenario Because Multiple Values Are Sent, Instead Of Specifying Single Value That Matches Multiple Objects. With Other Words There Is One To One Relation Between The Provided And Processed Objects.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
    </command:examples>
    <maml:relatedLinks>
      <maml:navigationLink>
        <maml:linkText> svesavov / SnsPsAdGroupMembers - </maml:linkText>
        <maml:uri>https://github.com/svesavov/SnsPsAdGroupMembers</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> PowerShell Gallery - </maml:linkText>
        <maml:uri>https://www.powershellgallery.com/packages/SnsPsAdGroupMembers/</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> Svetoslav Savov on LinkedIn - </maml:linkText>
        <maml:uri>https://www.linkedin.com/in/svetoslavsavov</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> SQLite V3 - </maml:linkText>
        <maml:uri>https://sqlite.org/index.html</maml:uri>
      </maml:navigationLink>
    </maml:relatedLinks>
  </command:command>
  <!-- Cmdlet: Remove-SnsAdManagedGroupContact -->
  <command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
    <command:details>
      <command:name>Remove-SnsAdManagedGroupContact</command:name>
      <command:verb>Remove</command:verb>
      <command:noun>SnsAdManagedGroupContact</command:noun>
      <maml:description>
        <maml:para>Removes Specified Notification Contacts From Specified Managed Active Directory Group Configuration.</maml:para>
      </maml:description>
    </command:details>
    <maml:description>
      <maml:para>Removes Specified Notification Contacts From Specified Managed Active Directory Group Configuration.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Operation Of "SnsPsAdGroupMembers" PSModule Install It With "AllUsers" Scope. The Idea Behind This Module Is To Be Used On A Scheduled Task "As Service" For The Actual Group Members Management, And Interactively By IT Administrators To Create And Modify The Managed Groups Configuration. This Requires The PSModule To Be Available To Multiple User Accounts.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Creation Of "SnsPsAdGroupMembers" PSModule DataBases, The First Load Of The PSModule Must Be In Elevated Mode. In The Normal Operation The PSModule Does Not Require Elevated Mode. More Information About That Is Provided Further In This Document.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"Why Should I Use This PSModule Instead Of Dynamic Groups?":</maml:para>
      <maml:para>- Well First And Foremost Reason Is Related With The Fact That This PowerShell Module Does Allow To Have Different Logic For Adding And Removing Members. This Is Not Achievable With Dynamic Groups.</maml:para>
      <maml:para>- The Company IT Department Might Need To Use A Single Group For Granting Access Rights In On Premises AD, AzureAD And Use It As Distribution List At The Same Time. Although This Can Be Achieved With Dynamic Groups You Have To Maintain At Least Two Of Them, One For On Premises AD And One For AzureAD.</maml:para>
      <maml:para>- There Are Cases Related With Certain AzureAD Functionalities And Synchronizations With Third Party Cloud Solutions Which Do Not Support Nested And Dynamic Groups. Managing Of Groups With Large Number Of Members In Corporate Environment Without Using Of Group Nestling Could Be Quite Tricky And Related With Lot Of Users Frustration And Administrative Effort.</maml:para>
      <maml:para>- The "SnsPsAdGroupMembers" PSModule Prepare Reports About Modifying Group Members And Audit Of Changes In The Group Management Settings. Whenever A Group Is Used For Granting Sensitive Access Rights Or Managing The Members Of A Sensitive Distribution List, The Group Owners Might Want To Receive Those Reports, Often Immediately After The Above-Mentioned Actions Are Taken.</maml:para>
      <maml:para>- The PSModule Can Be Used Only For Adding Or Only For Removing Members. Using Of Both Is Not Mandatory. This Does Allow Implementation Of Process For Adding Members In Sensitive Groups, Like "Domain Admins" For Example, Following Formal Approval Process, But Removing Members Immediately When The Person Who Owns The Account Leave The Company, Or Change The Position. In This Case There Will Be Zero Tolerance For Users "Forgotten" With More Than Needed Access Rights.</maml:para>
      <maml:para>This PSModule Have The Same Disadvantages And Requirements As The Dynamic Groups. Since The Management Logic Is Based On AD Attribute Values, It Requires The Used Ones To Be Up To Date And Consistent. Some Sort Of Synchronization From The Company HR System Would Address This. Such A Synchronization Is Nice To Have But Not A Requirement. Using My Other PSModule's Will Be Relatively Easy Creation Of Own Synchronization Related With Any On Premises HR Application. Most Of The Cloud Based Ones, Already Have Out Of The Box Synchronization Tools. Creation Of New One Would Not Be Feasible, But It Depends On The API's The Tool Provides.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Manages The Membership Of Active Directory Groups In A Single Domain Forest Based On Predefined Logic About Adding And Removing Members. For That Purpose, The PowerShell Module Uses SQLite Configuration DataBase To Keep Information About:</maml:para>
      <maml:para>- The Managed Groups.</maml:para>
      <maml:para>- The Logic For Adding Members Into Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- The Logic For Removing Members From Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- Explicit Group Inclusions. Those Are AD Objects Which Shall Be Added As Group Members, Although They Do Not Meet The Adding Criteria.</maml:para>
      <maml:para>- Explicit Group Exclusions. Those Are AD Objects Which Shall Not Be Added As Group Members, Although They Do Meet The Adding Criteria.</maml:para>
      <maml:para>- Notification Contacts Who Shall Receive Reports About The Actions And Audit Events Related With Their Own Groups.</maml:para>
      <maml:para>- The PSModule Configuration.</maml:para>
      <maml:para>- Managed Groups Configuration Changes Tracking.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Uses Another SQLite DataBase To Store All The Events Related With The CmdLets Operation And Events Related With Actions Taken On The Managed Groups.</maml:para>
      <maml:para></maml:para>
      <maml:para>To Increase The Confidence In The Automation Among The Group Owners, "SnsPsAdGroupMembers" PSModule Produces Reports Intended To Be Provided To Those Owners, Whenever The PSModule Adds And / Or Removes Members, Whenever It Detects Changes In The Groups Configuration That Might Affect The Group Members, Such Like Changes In The Add Logic, Remove Logic, Explicit Inclusions, Explicit Exclusions And Notification Contacts.</maml:para>
      <maml:para>In Case Of Changes In The Notification Contacts, Both The Old And New Contacts Are Included In The Report Recipients List. The Reports Are Prepared Only When Actual Changes Are Made Or Detected Whenever The Actual Group Management Occur. For That Purpose, The PSModule Uses An SQLite Statistics DataBase To Store Information About:</maml:para>
      <maml:para>- Events Related With Automatic Adding Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Automatic Removing Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Changes In Managed Groups Configuration That Might Affect The Group Membership, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With The Module Operation And Groups Management Intended To Be Provided To The Company IT's. The Internal Events Not Related With Specific Managed Group Are Not Kept In The Statistics DataBase. Therefore The Statistics DataBase Is Not Suitable Source Of Information About Troubleshooting Of Performance, Module Related Issues, And Script Related Issues. However It Is Perfectly Reliable Source Of Troubleshooting Information Related With Troubleshooting Of Incorrect Logic And Any Managed Groups Misconfiguration.</maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Only Prepares Reports And Reverts Them As "SnsReportCollection" Output Object. The Email Relay Options Differ From One Environment To Another, It Is Not Feasible To Maintain Multiple Settings Related With Email Sending In The Configuration DataBase, While Sending Of An Email From PowerShell Is Simple As Running Of A CmdLet. Depending On The Company, Might Be Used Different Languages, Different Wording, Company Branding, Company Stationaries, Company Colors And Company Visual Stylings In The Emails. From That Perspective The PSModule Reverts Reports In Custom Objects And Collections. The User Have To Convert Them To HTML Text And Send Them As Emails, Within The Automation Scripts Which Use "SnsPsAdGroupMembers" Module. The Simplest Way For Doing That Is Using "ConvertTo-Html" And "Send-MailMessage" Native PowerShell CmdLets. Whenever Managed Group Owners Are Not Interested To Receive Any Notifications The Reports For They Own Groups Can Be Disabled Via Leaving Empty The Notification Contacts Setting Of The Group (Or Remove All Notification Contacts For A Managed Group If There Are Already Specified). This Does Not Disable The Logging Of Events Into The Statistics DataBase.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>For DataBase Engine Is Used SQLite. SQLite Is Free Open Source Serverless DataBase, Which Comes With Its Own Advantages And Disadvantages. As Serverless DataBase There Is No Server To Manage The DataBase Requests And Locks. From That Perspective Using A Single SQLite DataBase Either Over Network Or Mapped Drives Or Simultaneously By Multiple Applications / PSSessions Might Lead To Errors In Accessing The DataBase Or DataBase Corruption.</maml:para>
      <maml:para>From That Perspective All The CmdLets Within This Module Have A Feature That Prevents Running Of Those CmdLets In Multiple PowerShell Sessions. All The CmdLets Have Parameter "Force" Which Allows The Usage Of The CmdLets In Multiple PSSessions, Use It At Your Own Risk. The Parameter Is Ignored And Does Not Work When The PSSession Is "As A Service" (In Automation Script Executed With Scheduled Task For Example).</maml:para>
      <maml:para>Both The Configuration And Statistics DataBases Are Located In "C:\ProgramData\SnsAdGroupMembers" By Default. In Order The Folder And DataBase Files To Be Created Properly, The First Run Of This CmdLet To Be Made In Elevated PowerShell Session. Creation Of The DataBase Folder And Setting The Required NTFS Permissions Requires Local Administrator Access Rights. The DataBase Files Can Be Moved / Migrated Into Different Folders, In That Case The Administrator Who Is Doing That Have To Make Sure That The Folder Exists, All The Users That Will Use This PSModule Will Have "Modify" NTFS Permissions Over The Folder And The DataBase Files, Move The DataBase Files Into The New Folder And Properly Provide The Module With The New Folder Absolute (Full) Path.</maml:para>
      <maml:para>Although Using This PSModule On Domain Controllers Is Possible, It Is Against The Best Practices And It Is Not Recommended. All Automations Shall Be Run On Dedicated Virtual Or Physical Machine. From That Perspective It Is Required "Local Admin" Access Rights.</maml:para>
      <maml:para>It Is Not Recommended The DataBase Files To Be Moved, And If That Happen They Shall Be Not Moved On Network Shares Or Mapped Drives. This Will Not Prevent The PSModule To Do Its Job. It Will Introduce Performance Degradation, Possible Interruption In Case Of Network Issues And Eventually Corruption Of The DataBases.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>Never Move DataBases Outside The Default Location When The PSModule Is Installed With Scope "CurrentUser".</maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>"CfgDbFolder" Setting Specifies The Location Of Both Configuration And Statistics DataBases Simultaneously Unless The Statistics DataBase Have Explicitly Specified Location. With Other Words When Modify Configuration DataBase Location And "StatDbFolder" Setting Is Not Used, Both DataBases Have To Be Moved In The New Location.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Contains CmdLets Intended To Be Run Interactively By The User And CmdLets Intended To Be Run Within Automation Scripts On A Schedule As A Service. The CmdLets Intended To Be Used Within Automation Scripts Comply With Additional Requirements Related With Logging, Reporting And Ability To Being Monitored (Using "SnsPsScriptsMonitoring" PSModule For Example). "Invoke-SnsAdGroupMembersManage" Is A CmdLet Intended To Be Used In An Automation Scripts. By Its Nature, This CmdLet Is An Automation Encapsulated Within A CmdLet. The Logs And Events Happening During The CmdLet Run Are Logged In An SQLite DataBase "GroupMembersProvStat.db" Referred Furter As Statistics DataBase. It Could Be Used For Other Reporting Purposes Like Periodical Comprehensive Reports About The Actions Taken By Automation Scripts (This Requires Additional Scripting To Read The DataBase And Prepare The Reports).</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>When Working With Active Directory It Is Important What Identity Attribute Will Be Chosen For Binding To The AD Objects. Although Naturally AD Uses DistinguishedName For Binding And LDAP Queries, It Is Not The Best Possible Identity. The DistinguishedName Is Unique But It Is Not Constant, It Can Be Changed Over The AD Object Life Cycle. An AD Object Can Be Renamed And / Or Moved Into Different Organizational Unit, Or The Organizational Unit Where The Object Is Located Can Be Renamed And / Or Moved. That Will Modify Object's Distinguished Name. In This Case The Active Directory Will Automatically Reflect Those Changes In The Attributes Of The Object And On All Relational Attributes Of The Remaining Objects Which Point To Our Object. For Example "member" Attribute Of All The Groups Where Our AD Object Is Member Of, Or "manager" Attribute Of All Accounts That Our User Is Manager. However AD Will Not Modify Accordingly The PSModule Configuration Stored In An External For The AD DataBase. This Will Lead To Errors And Failures.</maml:para>
      <maml:para>It Is Best Practice The AD Related Applications To Use For Binding Other Identity Attributes Which Do Not Change During The Objects Life Cycle. Those Are "objectGUID" And "objectSid". The Best Practices Gives Preference To The "objectSid" By Various Reasons. Since It Is Possible Groups To Have Member Objects Without "objectSid" (Contact Objects For Example) The "SnsPsAdGroupMembers" PSModule Uses As Identity The "ObjectGUID" Attribute. Thus Way When An Object Is Renamed Or Moved The PSModule Is Not Affected And Continue To Work As Intended.</maml:para>
      <maml:para>The The Well-Known AD Behavior, That When An Object Is Deleted And Then Recreated, All The Access Rights And Group Membership Are Lost, Is Related With The Fact That The Recreated Object Have Different "objectSid". Using The "objectGUID" As Identity Introduces Similar Behavior Of "SnsPsAdGroupMembers". Deletion And Recreation Of An AD Group Object Does Not Automatically Enable It For Automatic Members Management With The Logic Of The Deleted Group.</maml:para>
      <maml:para>The Using "objectGUID" As Identity In The PSModule Configuration Ensures That The PSModule Is Not Affected By Objects Rename Or Objects Move. When A Managed Group, Explicit Inclusion, Explicit Exclusion Is Renamed Or Moved Into Different OU, Their "objectGUID" Remains Intact. And The PSModule Continue To Bind To Those Objects Without Errors. However This Does Introduce Additional Overhead For The CmdLets Intended To Manage The Groups Configuration. When An Object Is Provided To Them They Need To Search For That Object In Active Directory, Enumerate The "objectGUID" Of The Object And Specify The Enumerated Value Into The Configuration DataBase. Since The CmdLets Query AD, That Query Can Be Made Against Multiple Attributes, Which Does Provide Freedom For The User To Use Multitude Of Values When An AD Object Is Provided To A Parameter. Please Refer To Each To The Parameters Sections Of Each CmdLet Help Document.</maml:para>
      <maml:para>When LDAP Queries Are Needed The Things Get More Complicated. The LDAP Queries Work Only With DistinguishedName. When You Need To Query About Reports Of A Person, Or Members Of A Group The AD Expects LDAP Query With DistinguishedName Values. An Example Of Often Use LDAP Query Clause Is:</maml:para>
      <maml:para>"(manager=CN=Jane Smith,CN=Users,DC=contoso,DC=com)"</maml:para>
      <maml:para>If "SnsPsAdGroupMembers" PSModule Keep It As Is Into The Configuration, In Case Of DistinguishedName Change, The Logic Will Revert No Results, Which Might Lead To Removal Of All The Members From The Group. Instead The LDAP Clause Is Stored Like:</maml:para>
      <maml:para>"(manager=00000000-0000-0000-0000-000000000000)"</maml:para>
      <maml:para>This Complicates The PSModule Further, As On The AD Managed Group Configuration Creation / Modification It Have To Evaluate The Specified Parameters, Match Them Using RegEx Pattern About Any Distinguished Names, Bind To The AD Object Using The Matched DistinguishedName, Enumerates The AD Object "objectGUID" And Amend The Matched DistinguishedName With The Enumerated "objectGUID". And Before The Actual AD Managed Group Members Management, It Have To Evaluate The Configuration About "objectGUID" Values Using RegEx Matching, Bind To The AD Object Using The Matched "objectGUID", Enumerate The AD Object DistinguishedName And Amend The "objectGUID" With The Enumerated DistinguishedName. Thus Way Introducing Overhead For The PSModule And For The Domain Controller Which Serves The LDAP Requests.</maml:para>
      <maml:para>To Reduce The Number Of The AD Requests And The Overhead, The PSModule Caches The Attributes Of The Previously Bind To Or Queried About AD Objects, And Consequently Uses The Cache Instead Of Making New AD Requests. The Effectiveness Of The AD Cache Depends On The Similarities In The Configuration Of The Groups.</maml:para>
      <maml:para>The Attributes Modified By The "SnsPsAdGroupMembers" PSModule Like "memberOf" AD Attribute, Are Never Cached. Caching Those Might Lead To False Positive Or Real Errors.</maml:para>
      <maml:para>The Values Of The AD Attributes Without Requirements For Uniqueness Cannot Be Used For Indexing And Searches In The Cache. For Example There Is No Uniqueness Requirement For "cn" Attribute, You Can Have Multiple Objects With The Same "cn" As Long As They Are Located In Different OU's. When A CmdLet Parameter From The PSModule Is Provided With "cn" Value, It Must Make LDAP Search To Enumerate The AD Object, Either To Confirm That The Value Corresponds To An AD Object Or To Throw Error About Multiple Objects. In Case We Have The Specified Value In The Cache It Is Not Certain That There Are No Other Objects With The Same Value In The AD Domain. Whenever We Use AD Attributes With Uniqueness Requirements Like Distinguished Name, For Example Presence Of The Provided Value In The Cache Can Be Safely Assumed As Correct And Unique, In That Case Query Against The AD Domain Is Not Needed. Usage Of Values In Attributes Without Uniqueness Requirements Reduces The Effectiveness Of The AD Cache Feature Further.</maml:para>
      <maml:para>Introducing A Cache In The PSModule Introduces All Generic Disadvantages Related With Caching, Like Cached Outdated Values. The "SnsPsAdGroupMembers" PSModule Keeps The AD Cache In The System Memory. This Does Ensure Maximum Speed For Accessing The Cache, With Negative Impact On The Machine Performance Because Of The Increased Memory Usage. Together With The Feature Which Does Not Allow Usage Of The PSModule In Multiple PSSession (Which Actually Force The Users To Close Their PSSessions Once They Finish Their Job), Ensures Relatively Short Life Span Of The Cached Entries, Thus Way Reducing The Cache Effectiveness But Increasing The Reliability Via Minimizing The Possibility For Issues Related With Outdated Entries.</maml:para>
      <maml:para>Although The Shorter Lifespan Of The Cached Entries Reduces The Possibility For Mistakes, It Does Not Eliminate Them Completely. Mistakes Might Happen Without Corrupted Or Outdated Cached Entry. Let Us Assume We Have A Department Related Group Where Members Are Added Based On Specific Value In The Department AD Attribute And Removed When The Value Is Different. At The Same Time, The Department AD Attribute Is Automatically Synchronized From The Company HR System. In Case Of Department Rebranding The Sync From The HR System Will Modify The Attribute Value Of All Department Members. In That Case All The Department Members Will Be Removed From The Group. This Is Addressed With Introducing Of New Feature Which Prevents Any Members Removal Whenever The Members Enumerated For Removing Are More Than Certain Threshold. The Threshold Is Configurable. The Default Value Is 50%.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" Provides A Feature Intended For Quick Identifying Whether A Group Is Automatically Managed Or Not, Which Is Disabled By Default. It Could Be Very Annoying And Frustrating To Manually Add Or Remove A Member Into A Group And The Automation To Revert The Changes Back Because The Member Does Not Match The Adding Or Match The Removing Criteria For The Automatic Group Members Management. Normally The IT Administrators Would Need To Check In The PS Module Configuration To Verify Whether An AD Group Is Automatically Managed Using The PSModule Before Membership Modification. This Might Lead To Failed Scheduled Tasks Due To Multiple PSSessions With The PSModule Loaded. From That Perspective "SnsPsAdGroupMembers" Stores A Predefined Constant Value In A Predefined AD Attribute Of The AD Managed Groups And Clears The Predefined Constant Value From The Predefined AD Attribute Of The Not Managed Groups. Therefore The Company IT Administrators Just Need To Look At That Attribute Before Manually Add Or Remove Groups Members In An AD Group.</maml:para>
      <maml:para>To Enable This Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet, To Specify An AD Attribute And A Constant Value Which Shall Be Set On The AD Managed Groups. To Disable That Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet To Clear Either The Value Or The AD Attribute Used By This Feature Or Both. When Enabled On A Scheduled Job After Actual Group Management "Invoke-SnsAdGroupMembersManage" Sets The Predefined Constant Value Into The Predefined AD Attribute Of All Enabled AD Managed Groups And Clears The Value From All Not Managed AD Groups. Therefore Once The Feature Is Disabled The User Have To Manually Clear The Value From The AD Attribute Of All The Groups In Case The Feature Was Ever Used. Changing The Attribute Will Not Clear The Value From The Old Attribute.</maml:para>
      <maml:para>NOTE: This Feature Considers As Managed Only The Groups That Are Enabled In The Groups Configuration. Disabling A Group From Automatic Members Management, Even Temporary Will Clear The AD Attribute Used By This Feature, Indicating To The Corporate IT Administrators, That The Group Membership Can Be Managed Manually.</maml:para>
      <maml:para>NOTE: This Feature Can Use Only AD Attributes With Type Of Single Valued String.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>Remove-SnsAdManagedGroupContact Is Intended To Be Used Interactively By A User To Remove A Notification Contact From A Managed AD Group Entry In The Configuration DataBase. In The Process Any Existing Not Specified Notification Contacts Remain Intact.</maml:para>
      <maml:para>NOTE: Please Make Sure That The PowerShell Is Closed, When You Finish With The Work On The Managed AD Groups Configuration. Otherwise Either The Other Users Or Any Automated Task Will Be Prevented From Work With The PSModule.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In Parameters Validations "Remove-SnsAdManagedGroupContact" CmdLet Enumerates The AD Managed Group Objects Corresponding To The Specified Group Identities And Verifies The Specified Notification Contact Emails In Active Directory. Whenever An Email Exists It Is Amended With The PrimarySmtpAddress Of The AD Object, In Case The Email Does Not Exists In The AD No Errors Are Thrown Allowing Recipients From Other Domains And External For The Organization Recipients. In Case The User Specifies A Value Different Than SMTP Address And The CmdLet Cannot Enumerate The PrimarySmtpAddress Of The AD Object An Error Is Thrown.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "BeginProcessing" Method "Remove-SnsAdManagedGroupContact" CmdLet Initializes The PSModule Configuration. Verifies The Existence, The Schema And The Integrity Of The Configuration DataBase. Verifies About Other PowerShell Processes Using "SnsPsAdGroupMembers" PSModule.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "ProcessRecord" Method "Remove-SnsAdManagedGroupContact" CmdLet Loops Each Specified Group Entry And Remove Each Specified Notification Contact From Each Group. Whenever A Specified Notification Contact Is Not Present In The AD Managed Group Configuration, A Warning Is Thrown. After The Removing Of All Specified Notification Contacts From The Group Configuration, The Group Object Is Normalized And Verified, Then Sent To The Pipeline.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The CmdLet Reverts SnsAdManagedGroup Objects With The Following Properties And Methods:</maml:para>
      <maml:para>- "Position" Property Of Type Integer. Represents The Group Position In The Collection For Members Management.</maml:para>
      <maml:para>- "Identity" Property Of Type Guid. Represents The Managed Group AD "objectGUID".</maml:para>
      <maml:para>- "Name" Property Of Type String. Contains The Value Of The Managed Group "cn" Attribute.</maml:para>
      <maml:para>- "AddLogic" Property Of Type String. Contains The Logic For Adding Members Into The Managed Group.</maml:para>
      <maml:para>- "RemoveLogic" Property Of Type String. Contains The Logic For Removing Members From The Managed Group.</maml:para>
      <maml:para>- "Inclusions" Property Of Type SnsAdManagedGroupInclusion Array. Contains An Array With The Group's Explicit Inclusions. Each SnsAdManagedGroupInclusion Object Contains: "Identity" Property Of Type Guid. "Name" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Exclusions" Property Of Type SnsAdManagedGroupExclusion Array. Contains An Array With The Group's Explicit Exclusions. Each SnsAdManagedGroupExclusion Object Contains: "Identity" Property Of Type Guid. "Name" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Notify" Property Of Type SnsAdManagedGroupContact Array. Contains An Array With The Group's Notification Contacts. Each SnsAdManagedGroupContact Object Contains: "Email" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Enabled" Property Of Type Boolean. Represents Whether The Managed Group Entry Is Active Or Not.</maml:para>
      <maml:para>- "GetSnsRawAddLogic" Method Intended To Revert The Not Normalized Add Logic As It Is Set In The Group Configuration.</maml:para>
      <maml:para>- "GetSnsRawRemoveLogic" Method Intended To Revert The Not Normalized Remove Logic As It Is Set In The Group Configuration.</maml:para>
    </maml:description>
    <command:syntax>
      <!-- Parameter set: __AllParameterSets -->
      <command:syntaxItem>
        <maml:name>Remove-SnsAdManagedGroupContact</maml:name>
        <!-- Parameter: Contact -->
        <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="NotificationContact,Email,Mail">
          <maml:name>Contact</maml:name>
          <maml:description>
            <maml:para>Specifies A Recipient To Remove From The Group Related Audit Reports.</maml:para>
            <maml:para></maml:para>
            <maml:para>The Parameter Accepts The Following Values:</maml:para>
            <maml:para>- SMTP Email Address.</maml:para>
            <maml:para>- SnsAdGroupMembers.SnsAdManagedGroupContact</maml:para>
            <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- distinguishedName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
            <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
            <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
            <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Notification Contact It Will Throw Error.</maml:para>
            <maml:para></maml:para>
            <maml:para>In Case Multiple Values Are Specified All Specified Contacts Will Be Removeed From The Specified Group.</maml:para>
            <maml:para>In Case Multiple Values Are Specified And Multiple Managed AD Groups Are Specified, All Specified Contacts Will Be Removeed From All Specified Groups.</maml:para>
          </maml:description>
          <command:parameterValue required="true">object</command:parameterValue>
          <dev:type>
            <maml:name>System.Object</maml:name>
            <maml:uri />
          </dev:type>
        </command:parameter>
        <!-- Parameter: Identity -->
        <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
          <maml:name>Identity</maml:name>
          <maml:description>
            <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
            <maml:para></maml:para>
            <maml:para>The Parameter Accepts The Following Values:</maml:para>
            <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
            <maml:para>- objectGUID</maml:para>
            <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
            <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
            <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
            <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
            <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
            <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
            <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
          </maml:description>
          <command:parameterValue required="true">object</command:parameterValue>
          <dev:type>
            <maml:name>System.Object</maml:name>
            <maml:uri />
          </dev:type>
        </command:parameter>
        <!-- Parameter: DomainController -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>DomainController</maml:name>
          <maml:description>
            <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
            <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
            <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
            <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
            <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
        <!-- Parameter: Force -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>Force</maml:name>
          <maml:description>
            <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue>False</dev:defaultValue>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
    <command:parameters>
      <!-- Parameter: Identity -->
      <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
        <maml:name>Identity</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
          <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
          <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
        <maml:name>Group</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
          <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
          <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
          <maml:para>This is an alias of the Identity parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
        <maml:name>ManagedGroup</maml:name>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
          <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
          <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
          <maml:para>This is an alias of the Identity parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <!-- Parameter: Contact -->
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="NotificationContact,Email,Mail">
        <maml:name>Contact</maml:name>
        <maml:description>
          <maml:para>Specifies A Recipient To Remove From The Group Related Audit Reports.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address.</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroupContact</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- distinguishedName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Notification Contact It Will Throw Error.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Contacts Will Be Removeed From The Specified Group.</maml:para>
          <maml:para>In Case Multiple Values Are Specified And Multiple Managed AD Groups Are Specified, All Specified Contacts Will Be Removeed From All Specified Groups.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="NotificationContact,Email,Mail">
        <maml:name>NotificationContact</maml:name>
        <maml:description>
          <maml:para>Specifies A Recipient To Remove From The Group Related Audit Reports.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address.</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroupContact</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- distinguishedName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Notification Contact It Will Throw Error.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Contacts Will Be Removeed From The Specified Group.</maml:para>
          <maml:para>In Case Multiple Values Are Specified And Multiple Managed AD Groups Are Specified, All Specified Contacts Will Be Removeed From All Specified Groups.</maml:para>
          <maml:para>This is an alias of the Contact parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="NotificationContact,Email,Mail">
        <maml:name>Email</maml:name>
        <maml:description>
          <maml:para>Specifies A Recipient To Remove From The Group Related Audit Reports.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address.</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroupContact</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- distinguishedName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Notification Contact It Will Throw Error.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Contacts Will Be Removeed From The Specified Group.</maml:para>
          <maml:para>In Case Multiple Values Are Specified And Multiple Managed AD Groups Are Specified, All Specified Contacts Will Be Removeed From All Specified Groups.</maml:para>
          <maml:para>This is an alias of the Contact parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="NotificationContact,Email,Mail">
        <maml:name>Mail</maml:name>
        <maml:description>
          <maml:para>Specifies A Recipient To Remove From The Group Related Audit Reports.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SMTP Email Address.</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroupContact</maml:para>
          <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- distinguishedName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
          <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
          <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Notification Contact It Will Throw Error.</maml:para>
          <maml:para></maml:para>
          <maml:para>In Case Multiple Values Are Specified All Specified Contacts Will Be Removeed From The Specified Group.</maml:para>
          <maml:para>In Case Multiple Values Are Specified And Multiple Managed AD Groups Are Specified, All Specified Contacts Will Be Removeed From All Specified Groups.</maml:para>
          <maml:para>This is an alias of the Contact parameter.</maml:para>
        </maml:description>
        <command:parameterValue required="true">object</command:parameterValue>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
      </command:parameter>
      <!-- Parameter: DomainController -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>DomainController</maml:name>
        <maml:description>
          <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
          <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
          <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
          <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
          <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
        </maml:description>
        <command:parameterValue required="true">string</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue></dev:defaultValue>
      </command:parameter>
      <!-- Parameter: Force -->
      <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
        <maml:name>Force</maml:name>
        <maml:description>
          <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
        </maml:description>
        <command:parameterValue required="true">SwitchParameter</command:parameterValue>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          <maml:uri />
        </dev:type>
        <dev:defaultValue>False</dev:defaultValue>
      </command:parameter>
    </command:parameters>
    <command:inputTypes>
      <command:inputType>
        <dev:type>
          <maml:name>System.Object</maml:name>
          <maml:uri />
        </dev:type>
        <maml:description>
          <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
          <maml:para></maml:para>
          <maml:para>The Parameter Accepts The Following Values:</maml:para>
          <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
          <maml:para>- objectGUID</maml:para>
          <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
          <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
          <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
          <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
          <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
          <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
          <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
        </maml:description>
      </command:inputType>
    </command:inputTypes>
    <command:returnValues>
      <!-- OutputType: SnsAdManagedGroup -->
      <command:returnValue>
        <dev:type>
          <maml:name>SnsAdGroupMembers.SnsAdManagedGroup</maml:name>
          <maml:uri />
        </dev:type>
      </command:returnValue>
    </command:returnValues>
    <maml:alertSet>
      <maml:title></maml:title>
      <maml:alert>
        <maml:para>AUTHOR: Svetoslav Nedyalkov Savov</maml:para>
        <maml:para>THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK</maml:para>
        <maml:para>OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.</maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
        <maml:para></maml:para>
      </maml:alert>
    </maml:alertSet>
    <command:examples>
      <command:example>
        <maml:title>---------- EXAMPLE 1 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Remove-SnsAdManagedGroupContact -Identity "Finance Department" `
-Contact "John Smith" -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Enumerates John Smith's PrimarySmtpAddress From AD And Remove The Address From AD Managed Group "Finance Department" Notification Contacts.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 2 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Remove-SnsAdManagedGroupContact -Identity "Finance Department" `
-Contact "John Smith", "john.smith@outlook.com" -Verbose;</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Enumerates John Smith's PrimarySmtpAddress From AD, "john.smith@outlook.com" Address Remains Unverified, And Remove Both Addresses From AD Managed Group "Finance Department" Notification Contacts.</maml:para>
          <maml:para>When Users From Other AD Domains In Multi Domain Forest Have To Be Removeed As Notification Contacts, Must Be Used Their Email Address. The CmdLet Will Not Be Able To Enumerate Their Accounts Outside Of The Current Domain.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 3 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Remove-SnsAdManagedGroupContact -Identity "*Finance*" `
-Contact "John Smith";</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Enumerates The Configuration Object For AD Managed Group "Finance Department" And Remove "John Smith" From Group's Notification Contacts. In Case The Wildcard Value Matches More Than One AD Managed Group A Terminating Error Will Be Thrown And The Request Will Be Not Completed.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
      <command:example>
        <maml:title>---------- EXAMPLE 4 ----------</maml:title>
        <dev:code>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = Get-SnsAdManagedGroup "*Finance*";</dev:code>
        <dev:remarks>
          <maml:para></maml:para>
          <maml:para>Enumerates The Configuration Objects For AD Managed Groups That Match The Wildcard Pattern.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
          <maml:para>$arrGrs;</maml:para>
          <maml:para></maml:para>
          <maml:para>Lists On The Host Window The Enumerated AD Managed Groups.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
          <maml:para>[SnsAdGroupMembers.SnsAdManagedGroup[]]$arrGrs = $arrGrs | Remove-SnsAdManagedGroupContact -Contact "John Smith";</maml:para>
          <maml:para></maml:para>
          <maml:para>Removes "John Smith" From All The Sent Via The Pipeline AD Managed Groups Notification Contacts. Use This If You Really Desperately Need To Workaround The Errors From The Previous Example. To List And Verify The Groups That Are Sent Via The Pipeline Before Executing The CmdLet Is More Than A Good Idea. There Are No Errors In This Scenario Because Multiple Values Are Sent, Instead Of Specifying Single Value That Matches Multiple Objects. With Other Words There Is One To One Relation Between The Provided And Processed Objects.</maml:para>
          <maml:para></maml:para>
          <maml:para></maml:para>
        </dev:remarks>
      </command:example>
    </command:examples>
    <maml:relatedLinks>
      <maml:navigationLink>
        <maml:linkText> svesavov / SnsPsAdGroupMembers - </maml:linkText>
        <maml:uri>https://github.com/svesavov/SnsPsAdGroupMembers</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> PowerShell Gallery - </maml:linkText>
        <maml:uri>https://www.powershellgallery.com/packages/SnsPsAdGroupMembers/</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> Svetoslav Savov on LinkedIn - </maml:linkText>
        <maml:uri>https://www.linkedin.com/in/svetoslavsavov</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText> SQLite V3 - </maml:linkText>
        <maml:uri>https://sqlite.org/index.html</maml:uri>
      </maml:navigationLink>
    </maml:relatedLinks>
  </command:command>
  <!-- Cmdlet: Set-SnsAdManagedGroupContact -->
  <command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
    <command:details>
      <command:name>Set-SnsAdManagedGroupContact</command:name>
      <command:verb>Set</command:verb>
      <command:noun>SnsAdManagedGroupContact</command:noun>
      <maml:description>
        <maml:para>Set Specified Emails As Managed Active Directory Group Notification Contact While Removing Any Existing Notification Contacts.</maml:para>
      </maml:description>
    </command:details>
    <maml:description>
      <maml:para>Set Specified Emails As Managed Active Directory Group Notification Contact While Removing Any Existing Notification Contacts.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Operation Of "SnsPsAdGroupMembers" PSModule Install It With "AllUsers" Scope. The Idea Behind This Module Is To Be Used On A Scheduled Task "As Service" For The Actual Group Members Management, And Interactively By IT Administrators To Create And Modify The Managed Groups Configuration. This Requires The PSModule To Be Available To Multiple User Accounts.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>To Ensure The Smooth Creation Of "SnsPsAdGroupMembers" PSModule DataBases, The First Load Of The PSModule Must Be In Elevated Mode. In The Normal Operation The PSModule Does Not Require Elevated Mode. More Information About That Is Provided Further In This Document.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"Why Should I Use This PSModule Instead Of Dynamic Groups?":</maml:para>
      <maml:para>- Well First And Foremost Reason Is Related With The Fact That This PowerShell Module Does Allow To Have Different Logic For Adding And Removing Members. This Is Not Achievable With Dynamic Groups.</maml:para>
      <maml:para>- The Company IT Department Might Need To Use A Single Group For Granting Access Rights In On Premises AD, AzureAD And Use It As Distribution List At The Same Time. Although This Can Be Achieved With Dynamic Groups You Have To Maintain At Least Two Of Them, One For On Premises AD And One For AzureAD.</maml:para>
      <maml:para>- There Are Cases Related With Certain AzureAD Functionalities And Synchronizations With Third Party Cloud Solutions Which Do Not Support Nested And Dynamic Groups. Managing Of Groups With Large Number Of Members In Corporate Environment Without Using Of Group Nestling Could Be Quite Tricky And Related With Lot Of Users Frustration And Administrative Effort.</maml:para>
      <maml:para>- The "SnsPsAdGroupMembers" PSModule Prepare Reports About Modifying Group Members And Audit Of Changes In The Group Management Settings. Whenever A Group Is Used For Granting Sensitive Access Rights Or Managing The Members Of A Sensitive Distribution List, The Group Owners Might Want To Receive Those Reports, Often Immediately After The Above-Mentioned Actions Are Taken.</maml:para>
      <maml:para>- The PSModule Can Be Used Only For Adding Or Only For Removing Members. Using Of Both Is Not Mandatory. This Does Allow Implementation Of Process For Adding Members In Sensitive Groups, Like "Domain Admins" For Example, Following Formal Approval Process, But Removing Members Immediately When The Person Who Owns The Account Leave The Company, Or Change The Position. In This Case There Will Be Zero Tolerance For Users "Forgotten" With More Than Needed Access Rights.</maml:para>
      <maml:para>This PSModule Have The Same Disadvantages And Requirements As The Dynamic Groups. Since The Management Logic Is Based On AD Attribute Values, It Requires The Used Ones To Be Up To Date And Consistent. Some Sort Of Synchronization From The Company HR System Would Address This. Such A Synchronization Is Nice To Have But Not A Requirement. Using My Other PSModule's Will Be Relatively Easy Creation Of Own Synchronization Related With Any On Premises HR Application. Most Of The Cloud Based Ones, Already Have Out Of The Box Synchronization Tools. Creation Of New One Would Not Be Feasible, But It Depends On The API's The Tool Provides.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Manages The Membership Of Active Directory Groups In A Single Domain Forest Based On Predefined Logic About Adding And Removing Members. For That Purpose, The PowerShell Module Uses SQLite Configuration DataBase To Keep Information About:</maml:para>
      <maml:para>- The Managed Groups.</maml:para>
      <maml:para>- The Logic For Adding Members Into Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- The Logic For Removing Members From Each Individual Group, Based On Attribute Values.</maml:para>
      <maml:para>- Explicit Group Inclusions. Those Are AD Objects Which Shall Be Added As Group Members, Although They Do Not Meet The Adding Criteria.</maml:para>
      <maml:para>- Explicit Group Exclusions. Those Are AD Objects Which Shall Not Be Added As Group Members, Although They Do Meet The Adding Criteria.</maml:para>
      <maml:para>- Notification Contacts Who Shall Receive Reports About The Actions And Audit Events Related With Their Own Groups.</maml:para>
      <maml:para>- The PSModule Configuration.</maml:para>
      <maml:para>- Managed Groups Configuration Changes Tracking.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Uses Another SQLite DataBase To Store All The Events Related With The CmdLets Operation And Events Related With Actions Taken On The Managed Groups.</maml:para>
      <maml:para></maml:para>
      <maml:para>To Increase The Confidence In The Automation Among The Group Owners, "SnsPsAdGroupMembers" PSModule Produces Reports Intended To Be Provided To Those Owners, Whenever The PSModule Adds And / Or Removes Members, Whenever It Detects Changes In The Groups Configuration That Might Affect The Group Members, Such Like Changes In The Add Logic, Remove Logic, Explicit Inclusions, Explicit Exclusions And Notification Contacts.</maml:para>
      <maml:para>In Case Of Changes In The Notification Contacts, Both The Old And New Contacts Are Included In The Report Recipients List. The Reports Are Prepared Only When Actual Changes Are Made Or Detected Whenever The Actual Group Management Occur. For That Purpose, The PSModule Uses An SQLite Statistics DataBase To Store Information About:</maml:para>
      <maml:para>- Events Related With Automatic Adding Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Automatic Removing Members Into Managed AD Group, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With Changes In Managed Groups Configuration That Might Affect The Group Membership, Regardless The Group Requires Or Not Notification Contacts Report.</maml:para>
      <maml:para>- Events Related With The Module Operation And Groups Management Intended To Be Provided To The Company IT's. The Internal Events Not Related With Specific Managed Group Are Not Kept In The Statistics DataBase. Therefore The Statistics DataBase Is Not Suitable Source Of Information About Troubleshooting Of Performance, Module Related Issues, And Script Related Issues. However It Is Perfectly Reliable Source Of Troubleshooting Information Related With Troubleshooting Of Incorrect Logic And Any Managed Groups Misconfiguration.</maml:para>
      <maml:para></maml:para>
      <maml:para>The PowerShell Module Only Prepares Reports And Reverts Them As "SnsReportCollection" Output Object. The Email Relay Options Differ From One Environment To Another, It Is Not Feasible To Maintain Multiple Settings Related With Email Sending In The Configuration DataBase, While Sending Of An Email From PowerShell Is Simple As Running Of A CmdLet. Depending On The Company, Might Be Used Different Languages, Different Wording, Company Branding, Company Stationaries, Company Colors And Company Visual Stylings In The Emails. From That Perspective The PSModule Reverts Reports In Custom Objects And Collections. The User Have To Convert Them To HTML Text And Send Them As Emails, Within The Automation Scripts Which Use "SnsPsAdGroupMembers" Module. The Simplest Way For Doing That Is Using "ConvertTo-Html" And "Send-MailMessage" Native PowerShell CmdLets. Whenever Managed Group Owners Are Not Interested To Receive Any Notifications The Reports For They Own Groups Can Be Disabled Via Leaving Empty The Notification Contacts Setting Of The Group (Or Remove All Notification Contacts For A Managed Group If There Are Already Specified). This Does Not Disable The Logging Of Events Into The Statistics DataBase.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>For DataBase Engine Is Used SQLite. SQLite Is Free Open Source Serverless DataBase, Which Comes With Its Own Advantages And Disadvantages. As Serverless DataBase There Is No Server To Manage The DataBase Requests And Locks. From That Perspective Using A Single SQLite DataBase Either Over Network Or Mapped Drives Or Simultaneously By Multiple Applications / PSSessions Might Lead To Errors In Accessing The DataBase Or DataBase Corruption.</maml:para>
      <maml:para>From That Perspective All The CmdLets Within This Module Have A Feature That Prevents Running Of Those CmdLets In Multiple PowerShell Sessions. All The CmdLets Have Parameter "Force" Which Allows The Usage Of The CmdLets In Multiple PSSessions, Use It At Your Own Risk. The Parameter Is Ignored And Does Not Work When The PSSession Is "As A Service" (In Automation Script Executed With Scheduled Task For Example).</maml:para>
      <maml:para>Both The Configuration And Statistics DataBases Are Located In "C:\ProgramData\SnsAdGroupMembers" By Default. In Order The Folder And DataBase Files To Be Created Properly, The First Run Of This CmdLet To Be Made In Elevated PowerShell Session. Creation Of The DataBase Folder And Setting The Required NTFS Permissions Requires Local Administrator Access Rights. The DataBase Files Can Be Moved / Migrated Into Different Folders, In That Case The Administrator Who Is Doing That Have To Make Sure That The Folder Exists, All The Users That Will Use This PSModule Will Have "Modify" NTFS Permissions Over The Folder And The DataBase Files, Move The DataBase Files Into The New Folder And Properly Provide The Module With The New Folder Absolute (Full) Path.</maml:para>
      <maml:para>Although Using This PSModule On Domain Controllers Is Possible, It Is Against The Best Practices And It Is Not Recommended. All Automations Shall Be Run On Dedicated Virtual Or Physical Machine. From That Perspective It Is Required "Local Admin" Access Rights.</maml:para>
      <maml:para>It Is Not Recommended The DataBase Files To Be Moved, And If That Happen They Shall Be Not Moved On Network Shares Or Mapped Drives. This Will Not Prevent The PSModule To Do Its Job. It Will Introduce Performance Degradation, Possible Interruption In Case Of Network Issues And Eventually Corruption Of The DataBases.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>Never Move DataBases Outside The Default Location When The PSModule Is Installed With Scope "CurrentUser".</maml:para>
      <maml:para></maml:para>
      <maml:para>!!! WARNING !!!</maml:para>
      <maml:para>"CfgDbFolder" Setting Specifies The Location Of Both Configuration And Statistics DataBases Simultaneously Unless The Statistics DataBase Have Explicitly Specified Location. With Other Words When Modify Configuration DataBase Location And "StatDbFolder" Setting Is Not Used, Both DataBases Have To Be Moved In The New Location.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" PSModule Contains CmdLets Intended To Be Run Interactively By The User And CmdLets Intended To Be Run Within Automation Scripts On A Schedule As A Service. The CmdLets Intended To Be Used Within Automation Scripts Comply With Additional Requirements Related With Logging, Reporting And Ability To Being Monitored (Using "SnsPsScriptsMonitoring" PSModule For Example). "Invoke-SnsAdGroupMembersManage" Is A CmdLet Intended To Be Used In An Automation Scripts. By Its Nature, This CmdLet Is An Automation Encapsulated Within A CmdLet. The Logs And Events Happening During The CmdLet Run Are Logged In An SQLite DataBase "GroupMembersProvStat.db" Referred Furter As Statistics DataBase. It Could Be Used For Other Reporting Purposes Like Periodical Comprehensive Reports About The Actions Taken By Automation Scripts (This Requires Additional Scripting To Read The DataBase And Prepare The Reports).</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>When Working With Active Directory It Is Important What Identity Attribute Will Be Chosen For Binding To The AD Objects. Although Naturally AD Uses DistinguishedName For Binding And LDAP Queries, It Is Not The Best Possible Identity. The DistinguishedName Is Unique But It Is Not Constant, It Can Be Changed Over The AD Object Life Cycle. An AD Object Can Be Renamed And / Or Moved Into Different Organizational Unit, Or The Organizational Unit Where The Object Is Located Can Be Renamed And / Or Moved. That Will Modify Object's Distinguished Name. In This Case The Active Directory Will Automatically Reflect Those Changes In The Attributes Of The Object And On All Relational Attributes Of The Remaining Objects Which Point To Our Object. For Example "member" Attribute Of All The Groups Where Our AD Object Is Member Of, Or "manager" Attribute Of All Accounts That Our User Is Manager. However AD Will Not Modify Accordingly The PSModule Configuration Stored In An External For The AD DataBase. This Will Lead To Errors And Failures.</maml:para>
      <maml:para>It Is Best Practice The AD Related Applications To Use For Binding Other Identity Attributes Which Do Not Change During The Objects Life Cycle. Those Are "objectGUID" And "objectSid". The Best Practices Gives Preference To The "objectSid" By Various Reasons. Since It Is Possible Groups To Have Member Objects Without "objectSid" (Contact Objects For Example) The "SnsPsAdGroupMembers" PSModule Uses As Identity The "ObjectGUID" Attribute. Thus Way When An Object Is Renamed Or Moved The PSModule Is Not Affected And Continue To Work As Intended.</maml:para>
      <maml:para>The The Well-Known AD Behavior, That When An Object Is Deleted And Then Recreated, All The Access Rights And Group Membership Are Lost, Is Related With The Fact That The Recreated Object Have Different "objectSid". Using The "objectGUID" As Identity Introduces Similar Behavior Of "SnsPsAdGroupMembers". Deletion And Recreation Of An AD Group Object Does Not Automatically Enable It For Automatic Members Management With The Logic Of The Deleted Group.</maml:para>
      <maml:para>The Using "objectGUID" As Identity In The PSModule Configuration Ensures That The PSModule Is Not Affected By Objects Rename Or Objects Move. When A Managed Group, Explicit Inclusion, Explicit Exclusion Is Renamed Or Moved Into Different OU, Their "objectGUID" Remains Intact. And The PSModule Continue To Bind To Those Objects Without Errors. However This Does Introduce Additional Overhead For The CmdLets Intended To Manage The Groups Configuration. When An Object Is Provided To Them They Need To Search For That Object In Active Directory, Enumerate The "objectGUID" Of The Object And Specify The Enumerated Value Into The Configuration DataBase. Since The CmdLets Query AD, That Query Can Be Made Against Multiple Attributes, Which Does Provide Freedom For The User To Use Multitude Of Values When An AD Object Is Provided To A Parameter. Please Refer To Each To The Parameters Sections Of Each CmdLet Help Document.</maml:para>
      <maml:para>When LDAP Queries Are Needed The Things Get More Complicated. The LDAP Queries Work Only With DistinguishedName. When You Need To Query About Reports Of A Person, Or Members Of A Group The AD Expects LDAP Query With DistinguishedName Values. An Example Of Often Use LDAP Query Clause Is:</maml:para>
      <maml:para>"(manager=CN=Jane Smith,CN=Users,DC=contoso,DC=com)"</maml:para>
      <maml:para>If "SnsPsAdGroupMembers" PSModule Keep It As Is Into The Configuration, In Case Of DistinguishedName Change, The Logic Will Revert No Results, Which Might Lead To Removal Of All The Members From The Group. Instead The LDAP Clause Is Stored Like:</maml:para>
      <maml:para>"(manager=00000000-0000-0000-0000-000000000000)"</maml:para>
      <maml:para>This Complicates The PSModule Further, As On The AD Managed Group Configuration Creation / Modification It Have To Evaluate The Specified Parameters, Match Them Using RegEx Pattern About Any Distinguished Names, Bind To The AD Object Using The Matched DistinguishedName, Enumerates The AD Object "objectGUID" And Amend The Matched DistinguishedName With The Enumerated "objectGUID". And Before The Actual AD Managed Group Members Management, It Have To Evaluate The Configuration About "objectGUID" Values Using RegEx Matching, Bind To The AD Object Using The Matched "objectGUID", Enumerate The AD Object DistinguishedName And Amend The "objectGUID" With The Enumerated DistinguishedName. Thus Way Introducing Overhead For The PSModule And For The Domain Controller Which Serves The LDAP Requests.</maml:para>
      <maml:para>To Reduce The Number Of The AD Requests And The Overhead, The PSModule Caches The Attributes Of The Previously Bind To Or Queried About AD Objects, And Consequently Uses The Cache Instead Of Making New AD Requests. The Effectiveness Of The AD Cache Depends On The Similarities In The Configuration Of The Groups.</maml:para>
      <maml:para>The Attributes Modified By The "SnsPsAdGroupMembers" PSModule Like "memberOf" AD Attribute, Are Never Cached. Caching Those Might Lead To False Positive Or Real Errors.</maml:para>
      <maml:para>The Values Of The AD Attributes Without Requirements For Uniqueness Cannot Be Used For Indexing And Searches In The Cache. For Example There Is No Uniqueness Requirement For "cn" Attribute, You Can Have Multiple Objects With The Same "cn" As Long As They Are Located In Different OU's. When A CmdLet Parameter From The PSModule Is Provided With "cn" Value, It Must Make LDAP Search To Enumerate The AD Object, Either To Confirm That The Value Corresponds To An AD Object Or To Throw Error About Multiple Objects. In Case We Have The Specified Value In The Cache It Is Not Certain That There Are No Other Objects With The Same Value In The AD Domain. Whenever We Use AD Attributes With Uniqueness Requirements Like Distinguished Name, For Example Presence Of The Provided Value In The Cache Can Be Safely Assumed As Correct And Unique, In That Case Query Against The AD Domain Is Not Needed. Usage Of Values In Attributes Without Uniqueness Requirements Reduces The Effectiveness Of The AD Cache Feature Further.</maml:para>
      <maml:para>Introducing A Cache In The PSModule Introduces All Generic Disadvantages Related With Caching, Like Cached Outdated Values. The "SnsPsAdGroupMembers" PSModule Keeps The AD Cache In The System Memory. This Does Ensure Maximum Speed For Accessing The Cache, With Negative Impact On The Machine Performance Because Of The Increased Memory Usage. Together With The Feature Which Does Not Allow Usage Of The PSModule In Multiple PSSession (Which Actually Force The Users To Close Their PSSessions Once They Finish Their Job), Ensures Relatively Short Life Span Of The Cached Entries, Thus Way Reducing The Cache Effectiveness But Increasing The Reliability Via Minimizing The Possibility For Issues Related With Outdated Entries.</maml:para>
      <maml:para>Although The Shorter Lifespan Of The Cached Entries Reduces The Possibility For Mistakes, It Does Not Eliminate Them Completely. Mistakes Might Happen Without Corrupted Or Outdated Cached Entry. Let Us Assume We Have A Department Related Group Where Members Are Added Based On Specific Value In The Department AD Attribute And Removed When The Value Is Different. At The Same Time, The Department AD Attribute Is Automatically Synchronized From The Company HR System. In Case Of Department Rebranding The Sync From The HR System Will Modify The Attribute Value Of All Department Members. In That Case All The Department Members Will Be Removed From The Group. This Is Addressed With Introducing Of New Feature Which Prevents Any Members Removal Whenever The Members Enumerated For Removing Are More Than Certain Threshold. The Threshold Is Configurable. The Default Value Is 50%.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>"SnsPsAdGroupMembers" Provides A Feature Intended For Quick Identifying Whether A Group Is Automatically Managed Or Not, Which Is Disabled By Default. It Could Be Very Annoying And Frustrating To Manually Add Or Remove A Member Into A Group And The Automation To Revert The Changes Back Because The Member Does Not Match The Adding Or Match The Removing Criteria For The Automatic Group Members Management. Normally The IT Administrators Would Need To Check In The PS Module Configuration To Verify Whether An AD Group Is Automatically Managed Using The PSModule Before Membership Modification. This Might Lead To Failed Scheduled Tasks Due To Multiple PSSessions With The PSModule Loaded. From That Perspective "SnsPsAdGroupMembers" Stores A Predefined Constant Value In A Predefined AD Attribute Of The AD Managed Groups And Clears The Predefined Constant Value From The Predefined AD Attribute Of The Not Managed Groups. Therefore The Company IT Administrators Just Need To Look At That Attribute Before Manually Add Or Remove Groups Members In An AD Group.</maml:para>
      <maml:para>To Enable This Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet, To Specify An AD Attribute And A Constant Value Which Shall Be Set On The AD Managed Groups. To Disable That Feature Use "Set-SnsAdGroupMembersPsModuleSettings" CmdLet To Clear Either The Value Or The AD Attribute Used By This Feature Or Both. When Enabled On A Scheduled Job After Actual Group Management "Invoke-SnsAdGroupMembersManage" Sets The Predefined Constant Value Into The Predefined AD Attribute Of All Enabled AD Managed Groups And Clears The Value From All Not Managed AD Groups. Therefore Once The Feature Is Disabled The User Have To Manually Clear The Value From The AD Attribute Of All The Groups In Case The Feature Was Ever Used. Changing The Attribute Will Not Clear The Value From The Old Attribute.</maml:para>
      <maml:para>NOTE: This Feature Considers As Managed Only The Groups That Are Enabled In The Groups Configuration. Disabling A Group From Automatic Members Management, Even Temporary Will Clear The AD Attribute Used By This Feature, Indicating To The Corporate IT Administrators, That The Group Membership Can Be Managed Manually.</maml:para>
      <maml:para>NOTE: This Feature Can Use Only AD Attributes With Type Of Single Valued String.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>Set-SnsAdManagedGroupContact Is Intended To Be Used Interactively By A User To Set The Notification Contacts Of A Managed AD Group Entry In The Configuration DataBase. In The Process Any Existing Notification Contacts Are Removed.</maml:para>
      <maml:para>NOTE: Please Make Sure That The PowerShell Is Closed, When You Finish With The Work On The Managed AD Groups Configuration. Otherwise Either The Other Users Or Any Automated Task Will Be Prevented From Work With The PSModule.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In Parameters Validations "Set-SnsAdManagedGroupContact" CmdLet Enumerates The AD Managed Group Objects Corresponding To The Specified Group Identities And Verifies The Specified Notification Contact Emails In Active Directory. Whenever An Email Exists It Is Amended With The PrimarySmtpAddress Of The AD Object, In Case The Email Does Not Exists In The AD No Errors Are Thrown Allowing Recipients From Other Domains And External For The Organization Recipients. In Case The User Specifies A Value Different Than SMTP Address And The CmdLet Cannot Enumerate The PrimarySmtpAddress Of The AD Object An Error Is Thrown.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "BeginProcessing" Method "Set-SnsAdManagedGroupContact" CmdLet Initializes The PSModule Configuration. Verifies The Existence, The Schema And The Integrity Of The Configuration DataBase. Verifies About Other PowerShell Processes Using "SnsPsAdGroupMembers" PSModule.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>In "ProcessRecord" Method "Set-SnsAdManagedGroupContact" CmdLet Loops Each Specified Group Entry And Sets The Specified Notification Contacts To Each Specified Group. Whenever A Specified Notification Contact Is Already Present In The AD Managed Group Configuration, A Warning Is Thrown. Whenever An Existing Notification Contact Is Not Present Among The Specified Notification Contacts, It Is Removed. Additionally To The Standard PowerShell "ShouldProcess" Method For Asking Confirmation, Is Implemented "ShouldContinue" Method For Asking The User For Confirmation. "ShouldContinue" Method Was Implemented To Ignore The "Force" Parameter Value With A Reason. Once Because The Users Often Ignore The Fact That The Existing Notification Contacts Will Be Removed, And Second Because The CmdLet Is Intended To Be Used Interactively Only. With Other Words You Will Never Need To Execute The CmdLet Within Automated Script Which Will Fail Because The Force Parameter Is Ignored By "Should Continue" Method. However In "ShouldContinue" Method Were Implemented "YesToAll" And "NoToAll" Responses Which Are Missing By Default. After The Processing Of The Notification Contacts Of The Group, The Group Object Is Normalized And Verified, Then Sent To The Pipeline.</maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para></maml:para>
      <maml:para>The CmdLet Reverts SnsAdManagedGroup Objects With The Following Properties And Methods:</maml:para>
      <maml:para>- "Position" Property Of Type Integer. Represents The Group Position In The Collection For Members Management.</maml:para>
      <maml:para>- "Identity" Property Of Type Guid. Represents The Managed Group AD "objectGUID".</maml:para>
      <maml:para>- "Name" Property Of Type String. Contains The Value Of The Managed Group "cn" Attribute.</maml:para>
      <maml:para>- "AddLogic" Property Of Type String. Contains The Logic For Adding Members Into The Managed Group.</maml:para>
      <maml:para>- "RemoveLogic" Property Of Type String. Contains The Logic For Removing Members From The Managed Group.</maml:para>
      <maml:para>- "Inclusions" Property Of Type SnsAdManagedGroupInclusion Array. Contains An Array With The Group's Explicit Inclusions. Each SnsAdManagedGroupInclusion Object Contains: "Identity" Property Of Type Guid. "Name" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Exclusions" Property Of Type SnsAdManagedGroupExclusion Array. Contains An Array With The Group's Explicit Exclusions. Each SnsAdManagedGroupExclusion Object Contains: "Identity" Property Of Type Guid. "Name" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Notify" Property Of Type SnsAdManagedGroupContact Array. Contains An Array With The Group's Notification Contacts. Each SnsAdManagedGroupContact Object Contains: "Email" Property Of Type String. "Enabled" Property Of Type Boolean.</maml:para>
      <maml:para>- "Enabled" Property Of Type Boolean. Represents Whether The Managed Group Entry Is Active Or Not.</maml:para>
      <maml:para>- "GetSnsRawAddLogic" Method Intended To Revert The Not Normalized Add Logic As It Is Set In The Group Configuration.</maml:para>
      <maml:para>- "GetSnsRawRemoveLogic" Method Intended To Revert The Not Normalized Remove Logic As It Is Set In The Group Configuration.</maml:para>
    </maml:description>
    <command:syntax>
      <!-- Parameter set: __AllParameterSets -->
      <command:syntaxItem>
        <maml:name>Set-SnsAdManagedGroupContact</maml:name>
        <!-- Parameter: Contact -->
        <command:parameter required="true" globbing="false" pipelineInput="false" position="named" aliases="NotificationContact,Email,Mail">
          <maml:name>Contact</maml:name>
          <maml:description>
            <maml:para>Specifies Recipients For The Group Related Audit Reports.</maml:para>
            <maml:para></maml:para>
            <maml:para>The Parameter Accepts The Following Values:</maml:para>
            <maml:para>- SMTP Email Address. Can Be Used For External Recipients. Does Not Support Wildcard Characters.</maml:para>
            <maml:para>- Exchange Alias. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- cn. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- distinguishedName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
            <maml:para>- displayName. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- employeeID. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- name. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- sAMAccountName. Must Be Existing Either Account Or Group Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- telephoneNumber. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- userPrincipalName. Must Be Existing Account Object In The AD Domain. Supports Star (*) Wildcard Character For Multiple Characters. LDAP Does Not Support Single Wildcard Character.</maml:para>
            <maml:para>- objectGUID. Must Be Existing Either Account, Group Or Contact Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
            <maml:para>- objectSid. Must Be Existing Either Account Or Group Object In The AD Domain. Does Not Support Wildcard Characters.</maml:para>
            <maml:para></maml:para>
            <maml:para>In Case Multiple Values Are Specified All Specified Contacts Will Be Added To The Specified Group.</maml:para>
            <maml:para>In Case Multiple Values Are Specified And Multiple Managed AD Groups Are Specified, All Specified Contacts Will Be Added To All Specified Groups.</maml:para>
          </maml:description>
          <command:parameterValue required="true">object</command:parameterValue>
          <dev:type>
            <maml:name>System.Object</maml:name>
            <maml:uri />
          </dev:type>
        </command:parameter>
        <!-- Parameter: Identity -->
        <command:parameter required="true" globbing="false" pipelineInput="true (ByValue)" position="named" aliases="Group,ManagedGroup">
          <maml:name>Identity</maml:name>
          <maml:description>
            <maml:para>Specifies A Managed Domain Group Present In The Configuration.</maml:para>
            <maml:para></maml:para>
            <maml:para>The Parameter Accepts The Following Values:</maml:para>
            <maml:para>- SnsAdGroupMembers.SnsAdManagedGroup</maml:para>
            <maml:para>- objectGUID</maml:para>
            <maml:para>- cn (Allows Usage Of Wildcard Characters.)</maml:para>
            <maml:para>Allowed Wildcard Characters Usage In Both PowerShell And SQL Syntax:</maml:para>
            <maml:para>Star (*) And Percent (%) Are Used For Multiple Characters.</maml:para>
            <maml:para>Question Mark (?) And Underscore (_) Are Used For Single Character.</maml:para>
            <maml:para>The Wildcard Functionality Is To Be Used Only For Less Typing. In Case The CmdLet Is Unable To Unambiguously Identify The Managed AD Group It Will Throw Error.</maml:para>
            <maml:para>For Example If You Are Sure That An Identity "Finance*" Will Revert From The Groups Configuration A Single Group Named "Finance Department" You Can Save Time And Use It Instead For Typing "Finance Department". However If There Are Multiple Managed AD Groups Matching "Finance*" You Will Receive Error.</maml:para>
            <maml:para>The Specified Identity Is Validated Against The Configuration DataBase. Therefore Only The Managed AD Groups Counts. Any AD Groups Not Automatically Managed That Match "Finance*" Are Not Considered And Will Not Throw Error.</maml:para>
          </maml:description>
          <command:parameterValue required="true">object</command:parameterValue>
          <dev:type>
            <maml:name>System.Object</maml:name>
            <maml:uri />
          </dev:type>
        </command:parameter>
        <!-- Parameter: DomainController -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>DomainController</maml:name>
          <maml:description>
            <maml:para>Specifies A Domain Controller Fully Qualified Domain Name.</maml:para>
            <maml:para>If Omitted The CmdLet Will Run Against The Logon Server.</maml:para>
            <maml:para>Using Single Domain Controller For All Tasks Prevents Issues Related With AD Replication Delays.</maml:para>
            <maml:para>After Members Or Another Property Modification, The CmdLet Enumerates The Modified Value Back From AD To Verify Whether The Modifications Are Successful. To Ensure That The Enumeration Happens Against The Same Domain Controller Where The Changes Are Made, Instead Of One Where The AD Replication Did Not Occur Yet, The CmdLet Uses A Single Domain Controller.</maml:para>
            <maml:para>In Case The Domain Controller Used By The CmdLet Goes Down, The CmdLet Will Fail. In That Case Run The CmdLet Again And Either Specify Different Domain Controller Or Do Not Specify Any, The CmdLet Will Pick Some Up And Running Global Catalog Server.</maml:para>
          </maml:description>
          <command:parameterValue required="true">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
            <maml:uri />
          </dev:type>
          <dev:defaultValue></dev:defaultValue>
        </command:parameter>
        <!-- Parameter: Force -->
        <command:parameter required="false" globbing="false" pipelineInput="false" position="named">
          <maml:name>Force</maml:name>
          <maml:description>
            <maml:para>Specifies To Ignore The Errors Related With Multiple PSSessions.</maml:para>
            <maml:para>The Parameter Does Not Affect The Call To "ShouldContinue" PowerShell Method.</maml:para>
            <maml:para>After All This CmdLet Should Be Used Interactively.</maml:para>
          </maml:description>
          <command:parameterValue required="true">SwitchParameter</command:parameterValue>