en-US/OrphanedSid-Help.xml

<?xml version="1.0" encoding="utf-8"?>
<helpItems 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" schema="maml" xmlns="http://msh">
  <command:command>
    <command:details>
      <command:name>Find-OrphanedSid</command:name>
      <maml:description>
        <maml:para>Finds access control entries in Active Directory that grant rights to principals that no longer exist.</maml:para>
      </maml:description>
      <command:verb>Find</command:verb>
      <command:noun>OrphanedSid</command:noun>
    </command:details>
    <maml:description>
      <maml:para>Walks every object under one or more search bases, reads each security descriptor, resolves
every identity reference, and reports the ones that cannot be resolved.
Nothing is changed.
 
Each orphaned access control entry is written to the pipeline as an OrphanedSIDResult with
the object's distinguished name, the unresolvable SID, the rights it still grants, and an
analysis of where the SID probably came from.
The same rows are written to -OutputPath as
CSV when that parameter is given.
A summary (objects processed, orphaned SIDs found,
duration, peak memory) goes to the console and the log.
 
Results stream to batch files in the temp directory while the run is in progress so memory
stays flat on large OUs; the files are removed when the command finishes unless
-PreserveTempFiles is set.</maml:para>
    </maml:description>
    <command:syntax>
      <command:syntaxItem>
        <maml:name>Find-OrphanedSid</maml:name>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="0" aliases="DistinguishedName">
          <maml:name>SearchBase</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string[]</command:parameterValue>
          <dev:type>
            <maml:name>System.String[]</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="1" aliases="none">
          <maml:name>OutputPath</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="2" aliases="none">
          <maml:name>MaxRetries</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">int</command:parameterValue>
          <dev:type>
            <maml:name>System.Int32</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="3" aliases="none">
          <maml:name>ConfigPath</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="4" aliases="none">
          <maml:name>MaxMemoryUsageMB</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">int</command:parameterValue>
          <dev:type>
            <maml:name>System.Int32</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="5" aliases="none">
          <maml:name>LogPath</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="6" aliases="none">
          <maml:name>CorrelationId</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="7" aliases="none">
          <maml:name>LogLevel</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="none">
          <maml:name>IncludeInherited</maml:name>
          <maml:description />
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="none">
          <maml:name>PreserveTempFiles</maml:name>
          <maml:description />
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="none">
          <maml:name>SuppressConsoleOutput</maml:name>
          <maml:description />
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          </dev:type>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
    <command:parameters>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="3" aliases="none">
        <maml:name>ConfigPath</maml:name>
        <maml:description>
          <maml:para>JSON configuration file.
Only WellKnownSIDPatterns, ProtectedSIDs, BatchSize,
MemoryCheckInterval, EnableDetailedLogging, LogLevel, LogFilePath, EnableLogFileRotation
and MaxLogFileSizeMB are read.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="6" aliases="none">
        <maml:name>CorrelationId</maml:name>
        <maml:description>
          <maml:para>Identifier carried through every log line and result row.
Generated when omitted.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="Named" aliases="none">
        <maml:name>IncludeInherited</maml:name>
        <maml:description>
          <maml:para>Also report access control entries inherited from parent containers.
More rows and a longer
run; by default only explicit entries are reported.</maml:para>
        </maml:description>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="7" aliases="none">
        <maml:name>LogLevel</maml:name>
        <maml:description>
          <maml:para>Lowest level written to the log file.
Security events are written at every level.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="5" aliases="none">
        <maml:name>LogPath</maml:name>
        <maml:description>
          <maml:para>Log file.
Defaults to .\Logs\Find-OrphanedSid_&lt;yyyyMMdd_HHmmss&gt;.log under the current
directory.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="4" aliases="none">
        <maml:name>MaxMemoryUsageMB</maml:name>
        <maml:description>
          <maml:para>Working-set threshold in megabytes at which garbage collection is forced.
Default 1024.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.Int32</command:parameterValue>
        <dev:type>
          <maml:name>System.Int32</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="2" aliases="none">
        <maml:name>MaxRetries</maml:name>
        <maml:description>
          <maml:para>Retry attempts for a transient Active Directory failure on one object.
Default 3.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.Int32</command:parameterValue>
        <dev:type>
          <maml:name>System.Int32</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="1" aliases="none">
        <maml:name>OutputPath</maml:name>
        <maml:description>
          <maml:para>CSV file to write the results to, in addition to the pipeline.
The parent folder must exist.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="Named" aliases="none">
        <maml:name>PreserveTempFiles</maml:name>
        <maml:description>
          <maml:para>Keep the streaming batch files under $env:TEMP\OrphanedSid-&lt;CorrelationId&gt;\ for
inspection after the run.</maml:para>
        </maml:description>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="true (ByValue, ByPropertyName)" position="0" aliases="DistinguishedName">
        <maml:name>SearchBase</maml:name>
        <maml:description>
          <maml:para>Distinguished name of one or more containers to search.
Accepts pipeline input.
Defaults to
the current domain root when omitted.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String[]</command:parameterValue>
        <dev:type>
          <maml:name>System.String[]</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="Named" aliases="none">
        <maml:name>SuppressConsoleOutput</maml:name>
        <maml:description>
          <maml:para>Write progress and the summary to the log file only.</maml:para>
        </maml:description>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
        </dev:type>
      </command:parameter>
    </command:parameters>
    <command:inputTypes>
      <command:inputType>
        <dev:type>
          <maml:name>System.String[]</maml:name>
        </dev:type>
        <maml:description>
          <maml:para>Distinguished names, by value or by the `DistinguishedName` property of a piped object such as the
output of `Get-ADOrganizationalUnit` or `Get-ADObject`.</maml:para>
        </maml:description>
      </command:inputType>
    </command:inputTypes>
    <command:returnValues>
      <command:returnValue>
        <dev:type>
          <maml:name>OrphanedSIDResult</maml:name>
        </dev:type>
        <maml:description>
          <maml:para>One object per orphaned access control entry, with `ObjectDN`, `ObjectClass`, `OrphanedSID`,
`LikelySource`, `Confidence`, `AnalysisNotes`, `AccessControlType`, `ActiveDirectoryRights`,
`InheritanceType`, `ObjectType`, `InheritedObjectType`, `IsInherited`, `ProcessingMethod`,
`ActionTaken`, `CorrelationId` and `Timestamp`.</maml:para>
        </maml:description>
      </command:returnValue>
    </command:returnValues>
    <maml:alertSet>
      <maml:alert>
        <maml:para>Author: Jeffrey Stuhr
Blog: https://www.techbyjeff.net
LinkedIn: https://www.linkedin.com/in/jeffrey-stuhr-034214aa/
 
Requires the RSAT ActiveDirectory module and read access to the objects under -SearchBase.
 
TROUBLESHOOTING:
- Common issues: https://github.com/fadwen/OrphanedSid/blob/main/Troubleshooting/Common/Common-Issues.md
- Security descriptors: https://github.com/fadwen/OrphanedSid/blob/main/Troubleshooting/Security/Security-Descriptor-Issues.md
- Memory: https://github.com/fadwen/OrphanedSid/blob/main/Troubleshooting/Performance/Memory-Management.md</maml:para>
      </maml:alert>
    </maml:alertSet>
    <command:examples>
      <command:example>
        <maml:title>--------- EXAMPLE 1 ---------</maml:title>
        <maml:introduction>
          <maml:para>Find-OrphanedSid -SearchBase 'OU=Users,DC=contoso,DC=com'</maml:para>
          <maml:para>&#x80;</maml:para>
          <maml:para>DESCRIPTION: Lists every orphaned ACE under the Users OU
OUTPUT: One OrphanedSIDResult per orphaned access control entry
USE CASE: A first look at how much cleanup an OU needs</maml:para>
        </maml:introduction>
        <dev:code />
        <dev:remarks />
      </command:example>
      <command:example>
        <maml:title>--------- EXAMPLE 2 ---------</maml:title>
        <maml:introduction>
          <maml:para>Find-OrphanedSid -SearchBase 'DC=contoso,DC=com' -IncludeInherited -OutputPath '.\Reports\audit.csv'</maml:para>
          <maml:para>&#x80;</maml:para>
          <maml:para>DESCRIPTION: Audits the whole domain including inherited entries and keeps a CSV
OUTPUT: Result objects on the pipeline and the same rows in audit.csv
USE CASE: Periodic compliance evidence</maml:para>
        </maml:introduction>
        <dev:code />
        <dev:remarks />
      </command:example>
      <command:example>
        <maml:title>--------- EXAMPLE 3 ---------</maml:title>
        <maml:introduction>
          <maml:para>Get-ADOrganizationalUnit -Filter * -SearchScope OneLevel |
        Find-OrphanedSid |
        Group-Object OrphanedSID |
        Sort-Object Count -Descending</maml:para>
          <maml:para>&#x80;</maml:para>
          <maml:para>DESCRIPTION: Pipes OUs in and groups the findings by SID
OUTPUT: The SIDs that appear most often across the domain
USE CASE: Deciding which deleted principals left the widest footprint</maml:para>
        </maml:introduction>
        <dev:code />
        <dev:remarks />
      </command:example>
    </command:examples>
    <command:relatedLinks>
      <maml:navigationLink>
        <maml:linkText>Online Version</maml:linkText>
        <maml:uri />
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText>Remove-OrphanedSid</maml:linkText>
        <maml:uri />
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText>Restore-OrphanedSidBackup</maml:linkText>
        <maml:uri />
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText>about_OrphanedSid</maml:linkText>
        <maml:uri />
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText>Common issues</maml:linkText>
        <maml:uri>https://github.com/fadwen/OrphanedSid/blob/main/Troubleshooting/Common/Common-Issues.md</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText>Security descriptor issues</maml:linkText>
        <maml:uri>https://github.com/fadwen/OrphanedSid/blob/main/Troubleshooting/Security/Security-Descriptor-Issues.md</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText>Memory management</maml:linkText>
        <maml:uri>https://github.com/fadwen/OrphanedSid/blob/main/Troubleshooting/Performance/Memory-Management.md</maml:uri>
      </maml:navigationLink>
    </command:relatedLinks>
  </command:command>
  <command:command>
    <command:details>
      <command:name>Remove-OrphanedSid</command:name>
      <maml:description>
        <maml:para>Removes orphaned access control entries from Active Directory objects after backing up each ACL.</maml:para>
      </maml:description>
      <command:verb>Remove</command:verb>
      <command:noun>OrphanedSid</command:noun>
    </command:details>
    <maml:description>
      <maml:para>Runs the same discovery as Find-OrphanedSid and then, for every object that carries an
orphaned entry, validates each SID against the protected and well-known SID lists, writes a
Clixml backup of the object's ACL, and removes the orphaned entries.
The backup for a run
lands in a timestamped folder so a whole run can be undone with Restore-OrphanedSidBackup.
 
The command has ConfirmImpact High: it asks once before changing anything.
-WhatIf previews
the run, listing the entries that would be removed, and creates no backup.
An unattended run
(scheduled task, CI) cannot answer the prompt and must pass -Force or -Confirm:$false.
 
Each removal is written to the pipeline as a RemovalOperationResult; -OutputPath writes the
discovered entries as CSV.</maml:para>
    </maml:description>
    <command:syntax>
      <command:syntaxItem>
        <maml:name>Remove-OrphanedSid</maml:name>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="0" aliases="DistinguishedName">
          <maml:name>SearchBase</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string[]</command:parameterValue>
          <dev:type>
            <maml:name>System.String[]</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="1" aliases="none">
          <maml:name>BackupPath</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="2" aliases="none">
          <maml:name>OutputPath</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="3" aliases="none">
          <maml:name>MaxRetries</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">int</command:parameterValue>
          <dev:type>
            <maml:name>System.Int32</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="4" aliases="none">
          <maml:name>ConfigPath</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="5" aliases="none">
          <maml:name>MaxMemoryUsageMB</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">int</command:parameterValue>
          <dev:type>
            <maml:name>System.Int32</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="6" aliases="none">
          <maml:name>LogPath</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="7" aliases="none">
          <maml:name>CorrelationId</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="8" aliases="none">
          <maml:name>LogLevel</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="none">
          <maml:name>Force</maml:name>
          <maml:description />
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="none">
          <maml:name>IncludeInherited</maml:name>
          <maml:description />
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="none">
          <maml:name>PreserveTempFiles</maml:name>
          <maml:description />
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="none">
          <maml:name>SuppressConsoleOutput</maml:name>
          <maml:description />
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="none">
          <maml:name>WhatIf</maml:name>
          <maml:description />
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="none">
          <maml:name>Confirm</maml:name>
          <maml:description />
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          </dev:type>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
    <command:parameters>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="1" aliases="none">
        <maml:name>BackupPath</maml:name>
        <maml:description>
          <maml:para>Folder that receives the per-run backup subfolder.
Defaults to .\Backup under the current
directory.
The parent folder must exist; the backup folder itself is created.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="4" aliases="none">
        <maml:name>ConfigPath</maml:name>
        <maml:description>
          <maml:para>JSON configuration file; see Find-OrphanedSid for the keys read.
ProtectedSIDs and
WellKnownSIDPatterns are the ones that matter here.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="Named" aliases="cf">
        <maml:name>Confirm</maml:name>
        <maml:description>
          <maml:para>Prompts you for confirmation before running the cmdlet.</maml:para>
        </maml:description>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="7" aliases="none">
        <maml:name>CorrelationId</maml:name>
        <maml:description>
          <maml:para>Identifier carried through every log line, backup file and result.
Generated when omitted.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="Named" aliases="none">
        <maml:name>Force</maml:name>
        <maml:description>
          <maml:para>Proceed without the confirmation prompt.
Required for unattended runs.
-WhatIf still wins.</maml:para>
        </maml:description>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="Named" aliases="none">
        <maml:name>IncludeInherited</maml:name>
        <maml:description>
          <maml:para>Also evaluate inherited access control entries.
Inherited entries cannot be removed from the
child object; they are reported and the parent is where the cleanup belongs.</maml:para>
        </maml:description>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="8" aliases="none">
        <maml:name>LogLevel</maml:name>
        <maml:description>
          <maml:para>Lowest level written to the log file.
Security events are written at every level.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="6" aliases="none">
        <maml:name>LogPath</maml:name>
        <maml:description>
          <maml:para>Log file.
Defaults to .\Logs\Remove-OrphanedSid_&lt;yyyyMMdd_HHmmss&gt;.log.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="5" aliases="none">
        <maml:name>MaxMemoryUsageMB</maml:name>
        <maml:description>
          <maml:para>Working-set threshold in megabytes at which garbage collection is forced.
Default 1024.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.Int32</command:parameterValue>
        <dev:type>
          <maml:name>System.Int32</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="3" aliases="none">
        <maml:name>MaxRetries</maml:name>
        <maml:description>
          <maml:para>Retry attempts for a transient Active Directory failure on one object.
Default 3.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.Int32</command:parameterValue>
        <dev:type>
          <maml:name>System.Int32</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="2" aliases="none">
        <maml:name>OutputPath</maml:name>
        <maml:description>
          <maml:para>CSV file for the discovered entries.
The parent folder must exist.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="Named" aliases="none">
        <maml:name>PreserveTempFiles</maml:name>
        <maml:description>
          <maml:para>Keep the streaming batch files after the run.</maml:para>
        </maml:description>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="true (ByValue, ByPropertyName)" position="0" aliases="DistinguishedName">
        <maml:name>SearchBase</maml:name>
        <maml:description>
          <maml:para>Distinguished name of one or more containers to clean.
Accepts pipeline input.
Defaults to
the current domain root when omitted.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String[]</command:parameterValue>
        <dev:type>
          <maml:name>System.String[]</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="Named" aliases="none">
        <maml:name>SuppressConsoleOutput</maml:name>
        <maml:description>
          <maml:para>Write progress and the summary to the log file only.</maml:para>
        </maml:description>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="Named" aliases="wi">
        <maml:name>WhatIf</maml:name>
        <maml:description>
          <maml:para>Runs the command in a mode that only reports what would happen without performing the actions.</maml:para>
        </maml:description>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
        </dev:type>
      </command:parameter>
    </command:parameters>
    <command:inputTypes>
      <command:inputType>
        <dev:type>
          <maml:name>System.String[]</maml:name>
        </dev:type>
        <maml:description>
          <maml:para>Distinguished names, by value or by the `DistinguishedName` property of a piped object such as the
output of `Get-ADOrganizationalUnit` or `Get-ADObject`.</maml:para>
        </maml:description>
      </command:inputType>
    </command:inputTypes>
    <command:returnValues>
      <command:returnValue>
        <dev:type>
          <maml:name>RemovalOperationResult</maml:name>
        </dev:type>
        <maml:description>
          <maml:para>One object per Active Directory object whose ACL was modified, with the object DN, the SIDs that
were intended for removal and the ones actually removed, the backup file written, the verification
outcome, any error, and the correlation ID.</maml:para>
        </maml:description>
      </command:returnValue>
    </command:returnValues>
    <maml:alertSet>
      <maml:alert>
        <maml:para>Author: Jeffrey Stuhr
Blog: https://www.techbyjeff.net
LinkedIn: https://www.linkedin.com/in/jeffrey-stuhr-034214aa/
 
Requires the RSAT ActiveDirectory module and write access to the security descriptor of
every object under -SearchBase (Modify Permissions).
SIDs in ProtectedSIDs and SIDs that
match WellKnownSIDPatterns are never removed.
 
TROUBLESHOOTING:
- Backups: https://github.com/fadwen/OrphanedSid/blob/main/Troubleshooting/Common/Backup-Restore-Issues.md
- Security validation: https://github.com/fadwen/OrphanedSid/blob/main/Troubleshooting/Security/Security-Validation-Guide.md</maml:para>
      </maml:alert>
    </maml:alertSet>
    <command:examples>
      <command:example>
        <maml:title>--------- EXAMPLE 1 ---------</maml:title>
        <maml:introduction>
          <maml:para>Remove-OrphanedSid -SearchBase 'OU=Decommissioned,DC=contoso,DC=com' -WhatIf</maml:para>
          <maml:para>&#x80;</maml:para>
          <maml:para>DESCRIPTION: Shows what would be removed without touching anything
OUTPUT: One WhatIf line per entry that would be removed
USE CASE: The review step before a cleanup</maml:para>
        </maml:introduction>
        <dev:code />
        <dev:remarks />
      </command:example>
      <command:example>
        <maml:title>--------- EXAMPLE 2 ---------</maml:title>
        <maml:introduction>
          <maml:para>Remove-OrphanedSid -SearchBase 'OU=Decommissioned,DC=contoso,DC=com' -BackupPath 'D:\ADBackups'</maml:para>
          <maml:para>&#x80;</maml:para>
          <maml:para>DESCRIPTION: Prompts once, backs up every affected ACL to D:\ADBackups\&lt;timestamp&gt;\, then removes
OUTPUT: One RemovalOperationResult per modified object
USE CASE: An interactive cleanup with the backup on a dedicated drive</maml:para>
        </maml:introduction>
        <dev:code />
        <dev:remarks />
      </command:example>
      <command:example>
        <maml:title>--------- EXAMPLE 3 ---------</maml:title>
        <maml:introduction>
          <maml:para>Remove-OrphanedSid -SearchBase 'OU=Servers,DC=contoso,DC=com' -Force -CorrelationId 'CHG0012345' -OutputPath '.\Reports\CHG0012345.csv'</maml:para>
          <maml:para>&#x80;</maml:para>
          <maml:para>DESCRIPTION: Unattended removal tagged with a change number
OUTPUT: Result objects, a CSV, a log and a backup folder that all carry CHG0012345
USE CASE: A scheduled task or a pipeline step</maml:para>
        </maml:introduction>
        <dev:code />
        <dev:remarks />
      </command:example>
    </command:examples>
    <command:relatedLinks>
      <maml:navigationLink>
        <maml:linkText>Online Version</maml:linkText>
        <maml:uri />
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText>Find-OrphanedSid</maml:linkText>
        <maml:uri />
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText>Restore-OrphanedSidBackup</maml:linkText>
        <maml:uri />
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText>about_OrphanedSid</maml:linkText>
        <maml:uri />
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText>Backup and restore guide</maml:linkText>
        <maml:uri>https://github.com/fadwen/OrphanedSid/blob/main/Documentation/Backup-and-Restore-Guide.md</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText>Security validation guide</maml:linkText>
        <maml:uri>https://github.com/fadwen/OrphanedSid/blob/main/Troubleshooting/Security/Security-Validation-Guide.md</maml:uri>
      </maml:navigationLink>
    </command:relatedLinks>
  </command:command>
  <command:command>
    <command:details>
      <command:name>Restore-OrphanedSidBackup</command:name>
      <maml:description>
        <maml:para>Restores Active Directory ACLs from a backup folder written by Remove-OrphanedSid.</maml:para>
      </maml:description>
      <command:verb>Restore</command:verb>
      <command:noun>OrphanedSidBackup</command:noun>
    </command:details>
    <maml:description>
      <maml:para>Reads the Clixml backup files in -BackupPath, validates each one (format, object DN, SDDL
and its SHA256 hash), applies the saved security descriptor to the object, and reads the
ACL back to verify the result.
 
-TargetObjectDN decides the scope.
A container (an OU or the domain root) restores every
object that is the container or sits under it.
A single object restores only backups whose recorded object DN equals
-TargetObjectDN, compared without regard to letter case.
Either way each object is restored once, from its most recent backup in the folder.
-BackupPath is the folder that holds the .xml files, normally one timestamped run
folder under the Remove-OrphanedSid backup root.
 
The command has ConfirmImpact High: it asks once before writing anything.
-WhatIf previews
the restore.
An unattended run must pass -Force or -Confirm:$false.
 
One result object per restored object is written to the pipeline; -OutputPath writes the
same rows as CSV.</maml:para>
    </maml:description>
    <command:syntax>
      <command:syntaxItem>
        <maml:name>Restore-OrphanedSidBackup</maml:name>
        <command:parameter required="true" variableLength="false" globbing="false" pipelineInput="false" position="0" aliases="DistinguishedName, SearchBase">
          <maml:name>TargetObjectDN</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string[]</command:parameterValue>
          <dev:type>
            <maml:name>System.String[]</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="true" variableLength="false" globbing="false" pipelineInput="false" position="1" aliases="none">
          <maml:name>BackupPath</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="2" aliases="none">
          <maml:name>OutputPath</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="3" aliases="none">
          <maml:name>LogPath</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="4" aliases="none">
          <maml:name>CorrelationId</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="5" aliases="none">
          <maml:name>LogLevel</maml:name>
          <maml:description />
          <command:parameterValue required="true" variableLength="false">string</command:parameterValue>
          <dev:type>
            <maml:name>System.String</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="none">
          <maml:name>Force</maml:name>
          <maml:description />
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="none">
          <maml:name>SuppressConsoleOutput</maml:name>
          <maml:description />
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="none">
          <maml:name>WhatIf</maml:name>
          <maml:description />
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          </dev:type>
        </command:parameter>
        <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named" aliases="none">
          <maml:name>Confirm</maml:name>
          <maml:description />
          <dev:type>
            <maml:name>System.Management.Automation.SwitchParameter</maml:name>
          </dev:type>
        </command:parameter>
      </command:syntaxItem>
    </command:syntax>
    <command:parameters>
      <command:parameter required="true" variableLength="false" globbing="false" pipelineInput="false" position="1" aliases="none">
        <maml:name>BackupPath</maml:name>
        <maml:description>
          <maml:para>Folder containing the backup .xml files.
Must exist.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="Named" aliases="cf">
        <maml:name>Confirm</maml:name>
        <maml:description>
          <maml:para>Prompts you for confirmation before running the cmdlet.</maml:para>
        </maml:description>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="4" aliases="none">
        <maml:name>CorrelationId</maml:name>
        <maml:description>
          <maml:para>Identifier carried through every log line and result.
Generated when omitted.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="Named" aliases="none">
        <maml:name>Force</maml:name>
        <maml:description>
          <maml:para>Proceed without the confirmation prompt.
Required for unattended runs.</maml:para>
        </maml:description>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="5" aliases="none">
        <maml:name>LogLevel</maml:name>
        <maml:description>
          <maml:para>Lowest level written to the log file.
Security events are written at every level.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="3" aliases="none">
        <maml:name>LogPath</maml:name>
        <maml:description>
          <maml:para>Log file.
Defaults to .\Logs\Restore-OrphanedSidBackup_&lt;yyyyMMdd_HHmmss&gt;.log.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="2" aliases="none">
        <maml:name>OutputPath</maml:name>
        <maml:description>
          <maml:para>CSV file for the restore results.
The parent folder must exist.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String</command:parameterValue>
        <dev:type>
          <maml:name>System.String</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="Named" aliases="none">
        <maml:name>SuppressConsoleOutput</maml:name>
        <maml:description>
          <maml:para>Write progress and the summary to the log file only.</maml:para>
        </maml:description>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="true" variableLength="false" globbing="false" pipelineInput="true (ByValue, ByPropertyName)" position="0" aliases="DistinguishedName, SearchBase">
        <maml:name>TargetObjectDN</maml:name>
        <maml:description>
          <maml:para>Distinguished name of the object or container to restore.
Accepts pipeline input.</maml:para>
        </maml:description>
        <command:parameterValue required="true" variableLength="true">System.String[]</command:parameterValue>
        <dev:type>
          <maml:name>System.String[]</maml:name>
        </dev:type>
      </command:parameter>
      <command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="Named" aliases="wi">
        <maml:name>WhatIf</maml:name>
        <maml:description>
          <maml:para>Runs the command in a mode that only reports what would happen without performing the actions.</maml:para>
        </maml:description>
        <dev:type>
          <maml:name>System.Management.Automation.SwitchParameter</maml:name>
        </dev:type>
      </command:parameter>
    </command:parameters>
    <command:inputTypes>
      <command:inputType>
        <dev:type>
          <maml:name>System.String[]</maml:name>
        </dev:type>
        <maml:description>
          <maml:para>Distinguished names, by value or by the `DistinguishedName` property of a piped object such as the
output of `Get-ADOrganizationalUnit` or `Get-ADObject`.</maml:para>
        </maml:description>
      </command:inputType>
    </command:inputTypes>
    <command:returnValues>
      <command:returnValue>
        <dev:type>
          <maml:name>RestoreWorkflowResult</maml:name>
        </dev:type>
        <maml:description>
          <maml:para>One object per target. For a container it summarises the run (`TotalObjects`,
`SuccessfulRestores`, `FailedRestores`, `IndividualResults`); for a single object it is that
object's restore result. Both carry `Success`, `TargetObjectDN`, `EntriesRestored`, `ErrorMessage`
and `CorrelationId`.</maml:para>
        </maml:description>
      </command:returnValue>
    </command:returnValues>
    <maml:alertSet>
      <maml:alert>
        <maml:para>Author: Jeffrey Stuhr
Blog: https://www.techbyjeff.net
LinkedIn: https://www.linkedin.com/in/jeffrey-stuhr-034214aa/
 
Requires the RSAT ActiveDirectory module and write access to the security descriptor of
each target object.
 
TROUBLESHOOTING:
- Backups and restores: https://github.com/fadwen/OrphanedSid/blob/main/Troubleshooting/Common/Backup-Restore-Issues.md</maml:para>
      </maml:alert>
    </maml:alertSet>
    <command:examples>
      <command:example>
        <maml:title>--------- EXAMPLE 1 ---------</maml:title>
        <maml:introduction>
          <maml:para>Restore-OrphanedSidBackup -TargetObjectDN 'CN=SRV01,OU=Servers,DC=contoso,DC=com' -BackupPath '.\Backup\20260703_104232' -WhatIf</maml:para>
          <maml:para>&#x80;</maml:para>
          <maml:para>DESCRIPTION: Shows which backup file would be applied to SRV01
OUTPUT: A WhatIf line naming the backup and the object
USE CASE: Confirming the right run folder before a rollback</maml:para>
        </maml:introduction>
        <dev:code />
        <dev:remarks />
      </command:example>
      <command:example>
        <maml:title>--------- EXAMPLE 2 ---------</maml:title>
        <maml:introduction>
          <maml:para>Restore-OrphanedSidBackup -TargetObjectDN 'OU=Servers,DC=contoso,DC=com' -BackupPath 'D:\ADBackups\20260703_104232' -Force</maml:para>
          <maml:para>&#x80;</maml:para>
          <maml:para>DESCRIPTION: Rolls back every object under the Servers OU from one run's backups, unattended
OUTPUT: One result per object with Success, EntriesRestored and any error
USE CASE: Undoing a cleanup that removed an entry still in use</maml:para>
        </maml:introduction>
        <dev:code />
        <dev:remarks />
      </command:example>
      <command:example>
        <maml:title>--------- EXAMPLE 3 ---------</maml:title>
        <maml:introduction>
          <maml:para>Import-Csv .\Reports\CHG0012345.csv | Select-Object -ExpandProperty ObjectDN -Unique |
        Restore-OrphanedSidBackup -BackupPath 'D:\ADBackups\20260703_104232' -Force</maml:para>
          <maml:para>&#x80;</maml:para>
          <maml:para>DESCRIPTION: Restores exactly the objects a removal run reported
OUTPUT: One result per object
USE CASE: Targeted rollback driven by the removal's own CSV</maml:para>
        </maml:introduction>
        <dev:code />
        <dev:remarks />
      </command:example>
    </command:examples>
    <command:relatedLinks>
      <maml:navigationLink>
        <maml:linkText>Online Version</maml:linkText>
        <maml:uri />
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText>Remove-OrphanedSid</maml:linkText>
        <maml:uri />
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText>Find-OrphanedSid</maml:linkText>
        <maml:uri />
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText>about_OrphanedSid</maml:linkText>
        <maml:uri />
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText>Backup and restore guide</maml:linkText>
        <maml:uri>https://github.com/fadwen/OrphanedSid/blob/main/Documentation/Backup-and-Restore-Guide.md</maml:uri>
      </maml:navigationLink>
      <maml:navigationLink>
        <maml:linkText>Backup and restore issues</maml:linkText>
        <maml:uri>https://github.com/fadwen/OrphanedSid/blob/main/Troubleshooting/Common/Backup-Restore-Issues.md</maml:uri>
      </maml:navigationLink>
    </command:relatedLinks>
  </command:command>
</helpItems>