So I am doing what sure seems like way too much work to do something rather simple in GUI. There seem to be many topics on this and I base my code off of their results, but it isn't working entirely. Hopefully an easy one for you folks! I am trying to take ownership of a path, be it a file or folder. I DO NOT want to use a separate module like PSCX as not all machines will have the module.
I created a function based off the code I found at the end of http://social.technet.microsoft.com/Forums/en-US/87679d43-04d5-4894-b35b-f37a6f5558cb/ that I can pass a path to singularly or I was hoping to be able to pipe Get-ChildItem to it. When I do "Get-ChildItem -Path D:\Permissions\TopFolder -Recurse -Force | Take-Ownership" it seemed to work, but then I noticed it only seems to work going one layer deep. The text output for troubleshooting shows it recursing all the way through, but yet Owner is not being set all the way down.
Folder layout:
D:\Permissions\TopFolder
D:\Permissions\TopFolder\FirstFolder
D:\Permissions\TopFolder\FirstFile.txt
D:\Permissions\TopFolder\FirstFolder\SecondFolder
D:\Permissions\TopFolder\FirstFolder\SecondFile.txt
D:\Permissions\TopFolder\FirstFolder\SecondFolder\ThirdFolder
D:\Permissions\TopFolder\FirstFolder\SecondFolder\ThirdFile.txt
Function Take-Ownership {
[CmdletBinding(DefaultParameterSetName=”Set01”)]
Param(
[parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=1,ParameterSetName='Set01')]
[string]$Path,
[parameter(Mandatory=$true,ValueFromPipelinebyPropertyName=$True,ParameterSetName='Set02')]
[Alias('FullName')][string]$FullPath
) # End of Param()
Begin {
#----------------------------------------------------------------
# Check that script was Run as Administrator
#----------------------------------------------------------------
If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
[Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Host -ForegroundColor Red -BackgroundColor Black "`n ERROR: You MUST have Administrator rights to run this script!"
Write-Host -ForegroundColor Red -BackgroundColor Black " Re-run this script as an Administrator!`n"
Break
}
#P/Invoke'd C# code to enable required privileges to take ownership and make changes when NTFS permissions are lacking
$AdjustTokenPrivileges = @"
using System;
using System.Runtime.InteropServices;
public class TokenManipulator
{
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
[DllImport("kernel32.dll", ExactSpelling = true)]
internal static extern IntPtr GetCurrentProcess();
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr
phtok);
[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool LookupPrivilegeValue(string host, string name,
ref long pluid);
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct TokPriv1Luid
{
public int Count;
public long Luid;
public int Attr;
}
internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
internal const int TOKEN_QUERY = 0x00000008;
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
public static bool AddPrivilege(string privilege)
{
try
{
bool retVal;
TokPriv1Luid tp;
IntPtr hproc = GetCurrentProcess();
IntPtr htok = IntPtr.Zero;
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
tp.Attr = SE_PRIVILEGE_ENABLED;
retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
return retVal;
}
catch (Exception ex)
{
throw ex;
}
}
public static bool RemovePrivilege(string privilege)
{
try
{
bool retVal;
TokPriv1Luid tp;
IntPtr hproc = GetCurrentProcess();
IntPtr htok = IntPtr.Zero;
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
tp.Attr = SE_PRIVILEGE_DISABLED;
retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
return retVal;
}
catch (Exception ex)
{
throw ex;
}
}
}"@
Add-Type $AdjustTokenPrivileges
# Activate necessary admin privileges to make changes without NTFS perms on the folder
[void][TokenManipulator]::AddPrivilege("SeRestorePrivilege") # Necessary to set Owner Permissions
[void][TokenManipulator]::AddPrivilege("SeBackupPrivilege") # Necessary to bypass Traverse Checking
[void][TokenManipulator]::AddPrivilege("SeTakeOwnershipPrivilege") # Necessary to override File Permissions
$Admin = New-Object System.Security.Principal.NTAccount("BUILTIN\Administrators")
$NewDirACL = New-Object System.Security.AccessControl.DirectorySecurity
$NewFileACL = New-Object System.Security.AccessControl.FileSecurity
$NewDirACL.SetOwner($Admin)
$NewFileACL.SetOwner($Admin)
} # End of Begin {}
Process {
if( $FullPath.Length -gt 0 ) {
if( Test-Path $FullPath ) {
$Path = $FullPath
}
}
if( Test-Path $Path -PathType Container ) {
"Take Ownership: $Path"
$Folder = Get-Item $Path -Force
$Folder.SetAccessControl($NewDirACL)
} elseif( Test-Path $Path -PathType Leaf ) {"Take Ownership: $Path"
$File = Get-Item $Path -Force
$File.SetAccessControl($NewFileACL)
} else {
Write-Host -ForegroundColor Red -BackgroundColor Black "ERROR: Path does not exist: $Path"
}
} # End of Process {}
End { } # End of End {}
} # End of Function Take-Ownership
To run this I have been doing:
PS D:\> $Folder = 'D:\Permissions\TopFolder' PS D:\> Get-Item $Folder | Get-Acl Directory: D:\Permissions Path Owner ---- ----- TopFolder DOMAIN\user1 PS D:\> Get-ChildItem $Folder -Force -Recurse | Get-Acl Directory: D:\Permissions\TopFolder Path Owner ---- ----- FirstFolder DOMAIN\user1 FirstFile.txt DOMAIN\user1 Directory: D:\Permissions\TopFolder\FirstFolder Path Owner ---- ----- SecondFolder DOMAIN\user1 SecondFile.txt DOMAIN\user1 Directory: D:\Permissions\TopFolder\FirstFolder\SecondFolder Path Owner ---- ----- ThirdFolder DOMAIN\user1 ThirdFile.txt DOMAIN\user1 PS D:\> PS D:\> Get-Item $Folder | Take-Ownership Take Ownership: D:\Permissions\TopFolder PS D:\> Get-ChildItem $Folder -Force -Recurse | Take-Ownership Take Ownership: D:\Permissions\TopFolder\FirstFolder Take Ownership: D:\Permissions\TopFolder\FirstFile.txt Take Ownership: D:\Permissions\TopFolder\FirstFolder\SecondFolder Take Ownership: D:\Permissions\TopFolder\FirstFolder\SecondFile.txt Take Ownership: D:\Permissions\TopFolder\FirstFolder\SecondFolder\ThirdFolder Take Ownership: D:\Permissions\TopFolder\FirstFolder\SecondFolder\ThirdFile.txt PS D:\> PS D:\> PS D:\> Get-Item $Folder | Get-Acl Directory: D:\Permissions Path Owner ---- ----- TopFolder BUILTIN\Administrators PS D:\> Get-ChildItem $Folder -Force -Recurse | Get-Acl Directory: D:\Permissions\TopFolder Path Owner ---- ----- FirstFolder BUILTIN\Administrators FirstFile.txt BUILTIN\Administrators Directory: D:\Permissions\TopFolder\FirstFolder Path Owner ---- ----- SecondFolder DOMAIN\user1 SecondFile.txt DOMAIN\user1 Directory: D:\Permissions\TopFolder\FirstFolder\SecondFolder Path Owner ---- ----- ThirdFolder DOMAIN\user1 ThirdFile.txt DOMAIN\user1 PS D:\>
I don't know why this isn't working. The output text shows I went through the subfolders and files...HELP!
Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.