Takeown.psm1

# Module created by Microsoft.PowerShell.Crescendo
class PowerShellCustomFunctionAttribute : System.Attribute { 
    [bool]$RequiresElevation
    [string]$Source
    PowerShellCustomFunctionAttribute() { $this.RequiresElevation = $false; $this.Source = "Microsoft.PowerShell.Crescendo" }
    PowerShellCustomFunctionAttribute([bool]$rElevation) {
        $this.RequiresElevation = $rElevation
        $this.Source = "Microsoft.PowerShell.Crescendo"
    }
}


<#
.Synopsis
PS wrapper module for takeown.exe
 
.DESCRIPTION
   See https://adam-bacon.netlify.app/recent-modules/takeown/
This tool allows an administrator to recover access to a file that was denied by re-assigning file ownership.
Original Parameter List with new parameter name given:
    /S system Specifies the remote system to
                                 connect to. Now -ComputerName
 
    /U [domain\]user Specifies the user context under
                                 which the command should execute. Now -RunAs
 
    /P [password] Specifies the password for the
                                 given user context.
                                 Prompts for input if omitted. Now -Password
 
    /F filename Specifies the filename or directory
                                 name pattern. Wildcard "*" can be used
                                 to specify the pattern. Allows sharename\filename. Now -Path
 
    /A Gives ownership to the administrators
                                 group instead of the current user. Now -GiveAdminGroupOwnership
 
    /R Recurse: instructs tool to operate on
                                 files in specified directory and all
                                 subdirectories. Now -Recurse
.NOTES
PARAMETER ComputerName
Specifies the computer to run this cmdlet against, this will default to the local machine if not used
PARAMETER RunAs
Allows you to specify a user account in Domain\User format to run the cmdlet as which in turn will use this account specified to take the ownership
PARAMETER Password
Only need to use this parameter if you have specified the -RunAs which will detail the username, then you use this parameter to specify the password
PARAMETER Path
This is used to specify the file path to the direcotory or file you wish to take ownership of
PARAMETER GiveAdminGroupOwnership
Will give ownership of the file or directory specified to the administrator group on the computer it is being run on
PARAMETER Recurse
This allows you to apply the given command recursively through all direcotries and sub-directories
PARAMETER SupressConfirmation
Please see the official documentation but this supports either a Y or a N for this parameter. The Y option will supress the confirmation and the N option will skip it
#>


function Set-Ownership
{
[PowerShellCustomFunctionAttribute(RequiresElevation=$False)]
[CmdletBinding()]

param(
[Parameter()]
[string]$ComputerName,
[Parameter()]
[string]$RunAs,
[Parameter()]
[string]$Password,
[Parameter()]
[string]$Path,
[Parameter()]
[switch]$GiveAdminGroupOwnership,
[Parameter()]
[switch]$Recurse,
[Parameter()]
[string]$SupressConfirmation
    )

BEGIN {
    $__PARAMETERMAP = @{
         ComputerName = @{
               OriginalName = '/s'
               OriginalPosition = '0'
               Position = '1'
               ParameterType = 'string'
               ApplyToExecutable = $False
               NoGap = $False
               }
         RunAs = @{
               OriginalName = '/u'
               OriginalPosition = '1'
               Position = '2'
               ParameterType = 'string'
               ApplyToExecutable = $False
               NoGap = $False
               }
         Password = @{
               OriginalName = '/p'
               OriginalPosition = '2'
               Position = '3'
               ParameterType = 'string'
               ApplyToExecutable = $False
               NoGap = $False
               }
         Path = @{
               OriginalName = '/f'
               OriginalPosition = '3'
               Position = '4'
               ParameterType = 'string'
               ApplyToExecutable = $False
               NoGap = $False
               }
         GiveAdminGroupOwnership = @{
               OriginalName = '/a'
               OriginalPosition = '4'
               Position = '5'
               ParameterType = 'switch'
               ApplyToExecutable = $False
               NoGap = $False
               }
         Recurse = @{
               OriginalName = '/r'
               OriginalPosition = '5'
               Position = '6'
               ParameterType = 'switch'
               ApplyToExecutable = $False
               NoGap = $False
               }
         SupressConfirmation = @{
               OriginalName = '/d'
               OriginalPosition = '6'
               Position = '7'
               ParameterType = 'string'
               ApplyToExecutable = $False
               NoGap = $False
               }
    }

    $__outputHandlers = @{ Default = @{ StreamOutput = $true; Handler = { $input } } }
}

PROCESS {
    $__boundParameters = $PSBoundParameters
    $__defaultValueParameters = $PSCmdlet.MyInvocation.MyCommand.Parameters.Values.Where({$_.Attributes.Where({$_.TypeId.Name -eq "PSDefaultValueAttribute"})}).Name
    $__defaultValueParameters.Where({ !$__boundParameters["$_"] }).ForEach({$__boundParameters["$_"] = get-variable -value $_})
    $__commandArgs = @()
    $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $__boundParameters[$_.Name]}).ForEach({$__boundParameters[$_.Name] = [switch]::new($false)})
    if ($__boundParameters["Debug"]){wait-debugger}
    foreach ($paramName in $__boundParameters.Keys|
            Where-Object {!$__PARAMETERMAP[$_].ApplyToExecutable}|
            Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) {
        $value = $__boundParameters[$paramName]
        $param = $__PARAMETERMAP[$paramName]
        if ($param) {
            if ($value -is [switch]) {
                 if ($value.IsPresent) {
                     if ($param.OriginalName) { $__commandArgs += $param.OriginalName }
                 }
                 elseif ($param.DefaultMissingValue) { $__commandArgs += $param.DefaultMissingValue }
            }
            elseif ( $param.NoGap ) {
                $pFmt = "{0}{1}"
                if($value -match "\s") { $pFmt = "{0}""{1}""" }
                $__commandArgs += $pFmt -f $param.OriginalName, $value
            }
            else {
                if($param.OriginalName) { $__commandArgs += $param.OriginalName }
                $__commandArgs += $value | Foreach-Object {$_}
            }
        }
    }
    $__commandArgs = $__commandArgs | Where-Object {$_ -ne $null}
    if ($__boundParameters["Debug"]){wait-debugger}
    if ( $__boundParameters["Verbose"]) {
         Write-Verbose -Verbose -Message takeown.exe
         $__commandArgs | Write-Verbose -Verbose
    }
    $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName]
    if (! $__handlerInfo ) {
        $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present
    }
    $__handler = $__handlerInfo.Handler
    if ( $PSCmdlet.ShouldProcess("takeown.exe $__commandArgs")) {
    # check for the application and throw if it cannot be found
        if ( -not (Get-Command -ErrorAction Ignore "takeown.exe")) {
          throw "Cannot find executable 'takeown.exe'"
        }
        if ( $__handlerInfo.StreamOutput ) {
            & "takeown.exe" $__commandArgs | & $__handler
        }
        else {
            $result = & "takeown.exe" $__commandArgs
            & $__handler $result
        }
    }
  } # end PROCESS

}