Functions/Resolve-Identity.ps1

# Copyright 2012 Aaron Jensen
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


function Resolve-Identity
{
    <#
    .SYNOPSIS
    Gets domain, name, type, and SID information about a user or group.
     
    .DESCRIPTION
    The `Resolve-Identity` function takes an identity name or security identifier (SID) and gets its canonical representation. It returns a `Carbon.Identity` object, which contains the following information about the identity:
 
     * Domain - the domain the user was found in
     * FullName - the users full name, e.g. Domain\Name
     * Name - the user's username or the group's name
     * Type - the Sid type.
     * Sid - the account's security identifier as a `System.Security.Principal.SecurityIdentifier` object.
     
    The common name for an account is not always the canonical name used by the operating system. For example, the local Administrators group is actually called BUILTIN\Administrators. This function uses the `LookupAccountName` and `LookupAccountSid` Windows functions to resolve an account name or security identifier into its domain, name, full name, SID, and SID type.
 
    You may pass a `System.Security.Principal.SecurityIdentifer`, a SID in SDDL form (as a string), or a SID in binary form (a byte array) as the value to the `SID` parameter. You'll get an error and nothing returned if the SDDL or byte array SID are invalid.
 
    If the name or security identifier doesn't represent an actual user or group, an error is written and nothing is returned.
 
    .LINK
    Test-Identity
 
    .LINK
    Resolve-IdentityName
 
    .LINK
    http://msdn.microsoft.com/en-us/library/system.security.principal.securityidentifier.aspx
 
    .LINK
    http://msdn.microsoft.com/en-us/library/windows/desktop/aa379601.aspx
     
    .LINK
    ConvertTo-SecurityIdentifier
 
    .LINK
    Resolve-IdentityName
 
    .LINK
    Test-Identity
 
    .OUTPUTS
    Carbon.Identity.
     
    .EXAMPLE
    Resolve-Identity -Name 'Administrators'
     
    Returns an object representing the `Administrators` group.
 
    .EXAMPLE
    Resolve-Identity -SID 'S-1-5-21-2678556459-1010642102-471947008-1017'
 
    Demonstrates how to use a SID in SDDL form to convert a SID into an identity.
 
    .EXAMPLE
    Resolve-Identity -SID (New-Object 'Security.Principal.SecurityIdentifier' 'S-1-5-21-2678556459-1010642102-471947008-1017')
 
    Demonstrates that you can pass a `SecurityIdentifier` object as the value of the SID parameter.
 
    .EXAMPLE
    Resolve-Identity -SID $sidBytes
 
    Demonstrates that you can use a byte array that represents a SID as the value of the `SID` parameter.
    #>

    [CmdletBinding(DefaultParameterSetName='ByName')]
    [OutputType([Carbon.Identity])]
    param(
        [Parameter(Mandatory=$true,ParameterSetName='ByName',Position=0)]
        [string]
        # The name of the identity to return.
        $Name,

        [Parameter(Mandatory=$true,ParameterSetName='BySid')]
        # The SID of the identity to return. Accepts a SID in SDDL form as a `string`, a `System.Security.Principal.SecurityIdentifier` object, or a SID in binary form as an array of bytes.
        $SID
    )

    Set-StrictMode -Version 'Latest'

    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState
    
    if( $PSCmdlet.ParameterSetName -eq 'BySid' )
    {
        $SID = ConvertTo-SecurityIdentifier -SID $SID
        if( -not $SID )
        {
            return
        }

        $id = [Carbon.Identity]::FindBySid( $SID )
        if( -not $id )
        {
            Write-Error ('Identity ''{0}'' not found.' -f $SID) -ErrorAction $ErrorActionPreference
        }
        return $id
    }
    
    if( -not (Test-Identity -Name $Name) )
    {
        Write-Error ('Identity ''{0}'' not found.' -f $Name) -ErrorAction $ErrorActionPreference
        return
    }

    return [Carbon.Identity]::FindByName( $Name ) 
}