Skip to content

Instantly share code, notes, and snippets.

@oldmate45
Forked from joshooaj/Restore-Ownership.ps1
Created November 22, 2023 04:30
Show Gist options
  • Select an option

  • Save oldmate45/1bc86c79eed1bd5686386d2bb64fc480 to your computer and use it in GitHub Desktop.

Select an option

Save oldmate45/1bc86c79eed1bd5686386d2bb64fc480 to your computer and use it in GitHub Desktop.
Take ownership of files/folders and restore permissions
function Restore-Ownership {
<#
.SYNOPSIS
Restores file/folder ownership for the current user or the Administrators group.
.DESCRIPTION
The `Restore-Ownership` cmdlet restores ownership of files and/or folders
for the current Windows user (default), or the BUILTIN\Administrators group.
This is accomplished using `takeown.exe` to take ownership of the file or
folder, followed by `Set-Acl` to add a `System.Security.AccessControl.FileSystemAccessRule`
granting FullAccess permissions.
.PARAMETER InputObject
Specifies one or more FileSystemInfo objects as are returned by
`Get-ChildItem` for example.
.PARAMETER Path
Specifies one or more file or folder paths with support for wildcards.
.PARAMETER LiteralPath
Specifies one or more literal file or folder paths.
.PARAMETER Administrators
Specifies that ownership and full access should be granted to the
BUILTIN\Administrators group instead of the current Windows user.
.PARAMETER Recurse
Specifies that ownership and full file/folder access permissions should be
restored for the specified path and all files/folders recursively.
.PARAMETER Force
Allows the cmdlet to get items that otherwise can't be accessed by the
user, such as hidden or system files.
.EXAMPLE
Get-ChildItem -Path C:\ProgramData\docker | Restore-Ownership -Administrators -Recurse -Force
Gets all items in the C:\ProgramData\docker directory and recursively sets
the file and folder ownership to the BUILTIN\Administrators group and grants the
same group FullControl privileges for all items in the the directory tree.
The `-Force` switch ensures that even hidden or system files are processed.
.EXAMPLE
Restore-Ownership -Path C:\temp\ -Recurse -Force | Remove-Item -Recurse -Force
Sets the file and folder ownership to the current Windows user on the
C:\temp\ directory and all subfolders and files recursively, grants the same
user FullControl privileges for all items in the directory tree, then
deletes the C:\temp\ folder and all contents.
#>
[CmdletBinding(DefaultParameterSetName = 'Path', SupportsShouldProcess)]
[OutputType([System.IO.FileSystemInfo])]
param(
[Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'FileSystemInfo')]
[ValidateNotNull()]
[System.IO.FileSystemInfo[]]
$InputObject,
[Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName, ParameterSetName="Path", Position = 0)]
[ValidateNotNullOrEmpty()]
[SupportsWildcards()]
[string[]]
$Path = ($PWD),
[Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName="LiteralPath", Position = 0)]
[ValidateNotNullOrEmpty()]
[string[]]
$LiteralPath,
[Parameter()]
[switch]
$Administrators,
[Parameter()]
[switch]
$Recurse,
[Parameter()]
[switch]
$Force
)
process {
if ($null -eq $InputObject) {
if ($Path) {
$InputObject = $Path | Get-Item -Force:$Force
} else {
$InputObject = $LiteralPath | ForEach-Object { Get-Item -LiteralPath $_ -Force:$Force }
}
}
foreach ($item in $InputObject) {
try {
$takeownArgs = @('/F', $item.FullName)
if ($Administrators) {
$takeownArgs += '/A'
}
if ($Recurse -and $item.PSIsContainer) {
$takeownArgs += @('/R', '/D', 'Y')
}
Write-Verbose "Executing takeown.exe $($takeownArgs -join ' ')"
& takeown.exe $takeownArgs | ForEach-Object {
Write-Information $_
}
if ($LASTEXITCODE) {
Write-Error "takeown.exe returned exit code $LASTEXITCODE" -ErrorAction Stop
}
$identity = 'BUILTIN\Administrators'
if (-not $Administrators) {
$identity = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
}
$stack = [system.collections.generic.stack[System.IO.FileSystemInfo]]::new()
$stack.Push($item)
do {
$currentItem = $stack.Pop()
Write-Verbose "Granting $identity FullControl to $($currentItem.FullName)"
$acl = $currentItem | Get-Acl -ErrorAction Stop
$rule = [security.accesscontrol.filesystemaccessrule]::new($identity, 'FullControl', 'Allow')
$acl.AddAccessRule($rule)
$acl | Set-Acl
if ($Recurse -and $currentItem.PSIsContainer) {
$currentItem | Get-ChildItem -Force:$Force | Foreach-Object {
$stack.Push($_)
}
}
} while ($stack.Count -gt 0)
$item
} catch {
Write-Error -ErrorRecord $_
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment