learn-powershell.net Open in urlscan Pro
192.0.78.25  Public Scan

Submitted URL: http://learn-powershell.net/2014/06/24/changing-ownership-of-file-or-folder-using-powershell/
Effective URL: https://learn-powershell.net/2014/06/24/changing-ownership-of-file-or-folder-using-powershell/
Submission: On February 22 via manual from AE — Scanned from DE

Form analysis 5 forms found in the DOM

POST https://learn-powershell.net/wp-comments-post.php

<form action="https://learn-powershell.net/wp-comments-post.php" method="post" id="commentform" class="comment-form"><input type="hidden" id="highlander_comment_nonce" name="highlander_comment_nonce" value="fdad9a814e"><input type="hidden"
    name="_wp_http_referer" value="/2014/06/24/changing-ownership-of-file-or-folder-using-powershell/">
  <input type="hidden" name="hc_post_as" id="hc_post_as" value="guest">
  <div class="comment-form-field comment-textarea">
    <div id="comment-form-comment"><textarea id="comment" name="comment" title="Enter your comment here..." placeholder="Enter your comment here..." style="overflow: hidden; overflow-wrap: break-word; resize: none; height: 38px;"></textarea></div>
  </div>
  <div id="comment-form-identity" style="display: none;">
    <div id="comment-form-nascar">
      <p>Fill in your details below or click an icon to log in:</p>
      <ul>
        <li class="selected" style="display:none;">
          <a href="#comment-form-guest" id="postas-guest" class="nascar-signin-link" title="Login via Guest">
									</a>
        </li>
        <li>
          <a href="#comment-form-load-service:WordPress.com" id="postas-wordpress" class="nascar-signin-link" title="Login via WordPress.com">
					<svg xmlns="http://www.w3.org/2000/svg" role="presentation" viewBox="0 0 24 24"><rect x="0" fill="none" width="24" height="24"></rect><g><path fill="#0087be" d="M12.158 12.786l-2.698 7.84c.806.236 1.657.365 2.54.365 1.047 0 2.05-.18 2.986-.51-.024-.037-.046-.078-.065-.123l-2.762-7.57zM3.008 12c0 3.56 2.07 6.634 5.068 8.092L3.788 8.342c-.5 1.117-.78 2.354-.78 3.658zm15.06-.454c0-1.112-.398-1.88-.74-2.48-.456-.74-.883-1.368-.883-2.11 0-.825.627-1.595 1.51-1.595.04 0 .078.006.116.008-1.598-1.464-3.73-2.36-6.07-2.36-3.14 0-5.904 1.613-7.512 4.053.21.008.41.012.58.012.94 0 2.395-.114 2.395-.114.484-.028.54.684.057.74 0 0-.487.058-1.03.086l3.275 9.74 1.968-5.902-1.4-3.838c-.485-.028-.944-.085-.944-.085-.486-.03-.43-.77.056-.742 0 0 1.484.114 2.368.114.94 0 2.397-.114 2.397-.114.486-.028.543.684.058.74 0 0-.488.058-1.03.086l3.25 9.665.897-2.997c.456-1.17.684-2.137.684-2.907zm1.82-3.86c.04.286.06.593.06.924 0 .912-.17 1.938-.683 3.22l-2.746 7.94c2.672-1.558 4.47-4.454 4.47-7.77 0-1.564-.4-3.033-1.1-4.314zM12 22C6.486 22 2 17.514 2 12S6.486 2 12 2s10 4.486 10 10-4.486 10-10 10z"></path></g></svg>				</a>
        </li>
        <li>
          <a href="#comment-form-load-service:Twitter" id="postas-twitter" class="nascar-signin-link" title="Login via Twitter">
					<svg xmlns="http://www.w3.org/2000/svg" role="presentation" viewBox="0 0 24 24"><rect x="0" fill="none" width="24" height="24"></rect><g><path fill="#1DA1F2" d="M22.23 5.924c-.736.326-1.527.547-2.357.646.847-.508 1.498-1.312 1.804-2.27-.793.47-1.67.812-2.606.996C18.325 4.498 17.258 4 16.078 4c-2.266 0-4.103 1.837-4.103 4.103 0 .322.036.635.106.935-3.41-.17-6.433-1.804-8.457-4.287-.353.607-.556 1.312-.556 2.064 0 1.424.724 2.68 1.825 3.415-.673-.022-1.305-.207-1.86-.514v.052c0 1.988 1.415 3.647 3.293 4.023-.344.095-.707.145-1.08.145-.265 0-.522-.026-.773-.074.522 1.63 2.038 2.817 3.833 2.85-1.404 1.1-3.174 1.757-5.096 1.757-.332 0-.66-.02-.98-.057 1.816 1.164 3.973 1.843 6.29 1.843 7.547 0 11.675-6.252 11.675-11.675 0-.178-.004-.355-.012-.53.802-.578 1.497-1.3 2.047-2.124z"></path></g></svg>				</a>
        </li>
        <li>
          <a href="#comment-form-load-service:Facebook" id="postas-facebook" class="nascar-signin-link" title="Login via Facebook">
					<svg xmlns="http://www.w3.org/2000/svg" role="presentation" viewBox="0 0 24 24"><rect x="0" fill="none" width="24" height="24"></rect><g><path fill="#3B5998" d="M20.007 3H3.993C3.445 3 3 3.445 3 3.993v16.013c0 .55.445.994.993.994h8.62v-6.97H10.27V11.31h2.346V9.31c0-2.325 1.42-3.59 3.494-3.59.993 0 1.847.073 2.096.106v2.43h-1.438c-1.128 0-1.346.537-1.346 1.324v1.734h2.69l-.35 2.717h-2.34V21h4.587c.548 0 .993-.445.993-.993V3.993c0-.548-.445-.993-.993-.993z"></path></g></svg>				</a>
        </li>
      </ul>
    </div>
    <div id="comment-form-guest" class="comment-form-service selected">
      <div class="comment-form-padder">
        <div class="comment-form-avatar">
          <a href="https://gravatar.com/site/signup/" target="_blank">				<img src="https://1.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?s=25" alt="Gravatar" width="25" class="no-grav grav-hashed grav-hijack" id="grav-ad516503a11cd5ca435acc9bb6523536-0">
</a>
        </div>
        <div class="comment-form-fields">
          <div class="comment-form-field comment-form-email">
            <label for="email">Email <span class="required">(required)</span> <span class="nopublish">(Address never made public)</span></label>
            <div class="comment-form-input"><input id="email" name="email" type="email" value=""></div>
          </div>
          <div class="comment-form-field comment-form-author">
            <label for="author">Name <span class="required">(required)</span></label>
            <div class="comment-form-input"><input id="author" name="author" type="text" value=""></div>
          </div>
          <div class="comment-form-field comment-form-url">
            <label for="url">Website</label>
            <div class="comment-form-input"><input id="url" name="url" type="url" value=""></div>
          </div>
        </div>
      </div>
    </div>
    <div id="comment-form-wordpress" class="comment-form-service">
      <div class="comment-form-padder">
        <div class="comment-form-avatar">
          <img src="https://1.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?s=25" alt="WordPress.com Logo" width="25" class="no-grav grav-hashed grav-hijack" id="grav-ad516503a11cd5ca435acc9bb6523536-1">
        </div>
        <div class="comment-form-fields">
          <input type="hidden" name="wp_avatar" id="wordpress-avatar" class="comment-meta-wordpress" value="">
          <input type="hidden" name="wp_user_id" id="wordpress-user_id" class="comment-meta-wordpress" value="">
          <input type="hidden" name="wp_access_token" id="wordpress-access_token" class="comment-meta-wordpress" value="">
          <p class="comment-form-posting-as pa-wordpress">
            <strong></strong> You are commenting using your WordPress.com account. <span class="comment-form-log-out"> (&nbsp;<a href="javascript:HighlanderComments.doExternalLogout( 'wordpress' );">Log&nbsp;Out</a>&nbsp;/&nbsp;
              <a href="#" onclick="javascript:HighlanderComments.switchAccount();return false;">Change</a>&nbsp;) </span>
            <span class="pa-icon"><svg xmlns="http://www.w3.org/2000/svg" role="presentation" viewBox="0 0 24 24">
                <rect x="0" fill="none" width="24" height="24"></rect>
                <g>
                  <path fill="#0087be"
                    d="M12.158 12.786l-2.698 7.84c.806.236 1.657.365 2.54.365 1.047 0 2.05-.18 2.986-.51-.024-.037-.046-.078-.065-.123l-2.762-7.57zM3.008 12c0 3.56 2.07 6.634 5.068 8.092L3.788 8.342c-.5 1.117-.78 2.354-.78 3.658zm15.06-.454c0-1.112-.398-1.88-.74-2.48-.456-.74-.883-1.368-.883-2.11 0-.825.627-1.595 1.51-1.595.04 0 .078.006.116.008-1.598-1.464-3.73-2.36-6.07-2.36-3.14 0-5.904 1.613-7.512 4.053.21.008.41.012.58.012.94 0 2.395-.114 2.395-.114.484-.028.54.684.057.74 0 0-.487.058-1.03.086l3.275 9.74 1.968-5.902-1.4-3.838c-.485-.028-.944-.085-.944-.085-.486-.03-.43-.77.056-.742 0 0 1.484.114 2.368.114.94 0 2.397-.114 2.397-.114.486-.028.543.684.058.74 0 0-.488.058-1.03.086l3.25 9.665.897-2.997c.456-1.17.684-2.137.684-2.907zm1.82-3.86c.04.286.06.593.06.924 0 .912-.17 1.938-.683 3.22l-2.746 7.94c2.672-1.558 4.47-4.454 4.47-7.77 0-1.564-.4-3.033-1.1-4.314zM12 22C6.486 22 2 17.514 2 12S6.486 2 12 2s10 4.486 10 10-4.486 10-10 10z">
                  </path>
                </g>
              </svg></span>
          </p>
        </div>
      </div>
    </div>
    <div id="comment-form-twitter" class="comment-form-service">
      <div class="comment-form-padder">
        <div class="comment-form-avatar">
          <img src="https://1.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?s=25" alt="Twitter picture" width="25" class="no-grav grav-hashed grav-hijack" id="grav-ad516503a11cd5ca435acc9bb6523536-2">
        </div>
        <div class="comment-form-fields">
          <input type="hidden" name="twitter_avatar" id="twitter-avatar" class="comment-meta-twitter" value="">
          <input type="hidden" name="twitter_user_id" id="twitter-user_id" class="comment-meta-twitter" value="">
          <input type="hidden" name="twitter_access_token" id="twitter-access_token" class="comment-meta-twitter" value="">
          <p class="comment-form-posting-as pa-twitter">
            <strong></strong> You are commenting using your Twitter account. <span class="comment-form-log-out"> (&nbsp;<a href="javascript:HighlanderComments.doExternalLogout( 'twitter' );">Log&nbsp;Out</a>&nbsp;/&nbsp;
              <a href="#" onclick="javascript:HighlanderComments.switchAccount();return false;">Change</a>&nbsp;) </span>
            <span class="pa-icon"><svg xmlns="http://www.w3.org/2000/svg" role="presentation" viewBox="0 0 24 24">
                <rect x="0" fill="none" width="24" height="24"></rect>
                <g>
                  <path fill="#1DA1F2"
                    d="M22.23 5.924c-.736.326-1.527.547-2.357.646.847-.508 1.498-1.312 1.804-2.27-.793.47-1.67.812-2.606.996C18.325 4.498 17.258 4 16.078 4c-2.266 0-4.103 1.837-4.103 4.103 0 .322.036.635.106.935-3.41-.17-6.433-1.804-8.457-4.287-.353.607-.556 1.312-.556 2.064 0 1.424.724 2.68 1.825 3.415-.673-.022-1.305-.207-1.86-.514v.052c0 1.988 1.415 3.647 3.293 4.023-.344.095-.707.145-1.08.145-.265 0-.522-.026-.773-.074.522 1.63 2.038 2.817 3.833 2.85-1.404 1.1-3.174 1.757-5.096 1.757-.332 0-.66-.02-.98-.057 1.816 1.164 3.973 1.843 6.29 1.843 7.547 0 11.675-6.252 11.675-11.675 0-.178-.004-.355-.012-.53.802-.578 1.497-1.3 2.047-2.124z">
                  </path>
                </g>
              </svg></span>
          </p>
        </div>
      </div>
    </div>
    <div id="comment-form-facebook" class="comment-form-service">
      <div class="comment-form-padder">
        <div class="comment-form-avatar">
          <img src="" alt="Facebook photo" width="25" class="no-grav">
        </div>
        <div class="comment-form-fields">
          <input type="hidden" name="fb_avatar" id="facebook-avatar" class="comment-meta-facebook" value="">
          <input type="hidden" name="fb_user_id" id="facebook-user_id" class="comment-meta-facebook" value="">
          <input type="hidden" name="fb_access_token" id="facebook-access_token" class="comment-meta-facebook" value="">
          <p class="comment-form-posting-as pa-facebook">
            <strong></strong> You are commenting using your Facebook account. <span class="comment-form-log-out"> (&nbsp;<a href="javascript:HighlanderComments.doExternalLogout( 'facebook' );">Log&nbsp;Out</a>&nbsp;/&nbsp;
              <a href="#" onclick="javascript:HighlanderComments.switchAccount();return false;">Change</a>&nbsp;) </span>
            <span class="pa-icon"><svg xmlns="http://www.w3.org/2000/svg" role="presentation" viewBox="0 0 24 24">
                <rect x="0" fill="none" width="24" height="24"></rect>
                <g>
                  <path fill="#3B5998"
                    d="M20.007 3H3.993C3.445 3 3 3.445 3 3.993v16.013c0 .55.445.994.993.994h8.62v-6.97H10.27V11.31h2.346V9.31c0-2.325 1.42-3.59 3.494-3.59.993 0 1.847.073 2.096.106v2.43h-1.438c-1.128 0-1.346.537-1.346 1.324v1.734h2.69l-.35 2.717h-2.34V21h4.587c.548 0 .993-.445.993-.993V3.993c0-.548-.445-.993-.993-.993z">
                  </path>
                </g>
              </svg></span>
          </p>
        </div>
      </div>
    </div>
    <div id="comment-form-load-service" class="comment-form-service">
      <div class="comment-form-posting-as-cancel"><a href="javascript:HighlanderComments.cancelExternalWindow();">Cancel</a></div>
      <p>Connecting to %s</p>
    </div>
  </div>
  <script type="text/javascript">
    var highlander_expando_javascript = function() {
      function hide(sel) {
        var el = document.querySelector(sel);
        if (el) {
          el.style.setProperty('display', 'none');
        }
      }

      function show(sel) {
        var el = document.querySelector(sel);
        if (el) {
          el.style.removeProperty('display');
        }
      }
      var input = document.createElement('input');
      var comment = document.querySelector('#comment');
      if (input && comment && 'placeholder' in input) {
        var label = document.querySelector('.comment-textarea label');
        if (label) {
          var text = label.textContent;
          label.parentNode.removeChild(label);
          comment.setAttribute('placeholder', text);
        }
      }
      // Expando Mode: start small, then auto-resize on first click + text length
      hide('#comment-form-identity');
      hide('#comment-form-subscribe');
      hide('#commentform .form-submit');
      if (comment) {
        comment.style.height = '10px';
        var handler = function() {
          comment.style.height = HighlanderComments.initialHeight + 'px';
          show('#comment-form-identity');
          show('#comment-form-subscribe');
          show('#commentform .form-submit');
          HighlanderComments.resizeCallback();
          comment.removeEventListener('focus', handler);
        };
        comment.addEventListener('focus', handler);
      }
    }
    if (document.readyState !== 'loading') {
      highlander_expando_javascript();
    } else {
      document.addEventListener('DOMContentLoaded', highlander_expando_javascript);
    }
  </script>
  <div id="comment-form-subscribe" style="display: none;">
    <p class="comment-subscription-form"><input type="checkbox" name="subscribe" id="subscribe" value="subscribe" style="width: auto;"> <label class="subscribe-label" id="subscribe-label" for="subscribe" style="display: inline;">Notify me of new
        comments via email.</label></p>
    <p class="post-subscription-form"><input type="checkbox" name="subscribe_blog" id="subscribe_blog" value="subscribe" style="width: auto;"> <label class="subscribe-label" id="subscribe-blog-label" for="subscribe_blog"
        style="display: inline;">Notify me of new posts via email.</label></p>
  </div>
  <p class="form-submit" style="display: none;"><input name="submit" type="submit" id="comment-submit" class="submit button" value="Post Comment"> <input type="hidden" name="comment_post_ID" value="5049" id="comment_post_ID">
    <input type="hidden" name="comment_parent" id="comment_parent" value="0">
  </p>
  <p style="display: none;"><input type="hidden" id="akismet_comment_nonce" name="akismet_comment_nonce" value="c2c4ad5332"></p>
  <input type="hidden" name="genseq" value="1677056616">
  <p style="display: none !important;"><label>Δ<textarea name="ak_hp_textarea" cols="45" rows="8" maxlength="100"></textarea></label><input type="hidden" id="ak_js_1" name="ak_js" value="1677056617096">
    <script>
      document.getElementById("ak_js_1").setAttribute("value", (new Date()).getTime());
    </script>
  </p>
</form>

GET https://learn-powershell.net/

<form role="search" method="get" id="searchform" class="searchform" action="https://learn-powershell.net/">
  <div>
    <label class="screen-reader-text" for="s">Search for:</label>
    <input type="text" value="" name="s" id="s">
    <input type="submit" id="searchsubmit" value="Search">
  </div>
</form>

GET https://learn-powershell.net

<form action="https://learn-powershell.net" method="get"><label class="screen-reader-text" for="cat">Categories</label><select name="cat" id="cat" class="postform">
    <option value="-1">Select Category</option>
    <option class="level-0" value="162381199">2013 Scripting Games Judges Notes</option>
    <option class="level-0" value="238274551">Debug</option>
    <option class="level-0" value="282714">Deep Dive</option>
    <option class="level-0" value="7744666">Excel</option>
    <option class="level-0" value="7168">GUI</option>
    <option class="level-0" value="31428">Modules</option>
    <option class="level-0" value="103">News</option>
    <option class="level-0" value="315">Office</option>
    <option class="level-0" value="19743086">PowerCLI</option>
    <option class="level-0" value="178495">powershell</option>
    <option class="level-0" value="56726985">Scripting Games 2011</option>
    <option class="level-0" value="82426987">Scripting Games 2012</option>
    <option class="level-0" value="159555771">Scripting Games 2013</option>
    <option class="level-0" value="4493">scripts</option>
    <option class="level-0" value="10346">SQL</option>
    <option class="level-0" value="456880">Tech-Ed</option>
    <option class="level-0" value="10118394">Tips</option>
    <option class="level-0" value="1">Uncategorized</option>
    <option class="level-0" value="31441">V3</option>
    <option class="level-0" value="694088">V4</option>
    <option class="level-0" value="23664898">V5</option>
    <option class="level-0" value="38600">VMWare</option>
    <option class="level-0" value="205592021">Winter Scripting Games 2014</option>
    <option class="level-0" value="46652">WPF</option>
    <option class="level-0" value="347217">WSUS</option>
  </select>
</form>

POST https://subscribe.wordpress.com

<form action="https://subscribe.wordpress.com" method="post" accept-charset="utf-8" data-blog="15063622" data-post_access_level="everybody" id="subscribe-blog">
  <p>Enter your email address to subscribe to this blog and receive notifications of new posts by email.</p>
  <p id="subscribe-email">
    <label id="subscribe-field-label" for="subscribe-field" class="screen-reader-text"> Email Address: </label>
    <input type="email" name="email" style="width: 95%; padding: 1px 10px" placeholder="Email Address" value="" id="subscribe-field" required="">
  </p>
  <p id="subscribe-submit">
    <input type="hidden" name="action" value="subscribe">
    <input type="hidden" name="blog_id" value="15063622">
    <input type="hidden" name="source" value="https://learn-powershell.net/2014/06/24/changing-ownership-of-file-or-folder-using-powershell/">
    <input type="hidden" name="sub-type" value="widget">
    <input type="hidden" name="redirect_fragment" value="subscribe-blog">
    <input type="hidden" id="_wpnonce" name="_wpnonce" value="e5033639db"> <button type="submit" class="wp-block-button__link"> Sign me up! </button>
  </p>
</form>

POST https://subscribe.wordpress.com

<form method="post" action="https://subscribe.wordpress.com" accept-charset="utf-8" style="display: none;">
  <div class="actnbr-follow-count">Join 479 other followers</div>
  <div>
    <input type="email" name="email" placeholder="Enter your email address" class="actnbr-email-field" aria-label="Enter your email address">
  </div>
  <input type="hidden" name="action" value="subscribe">
  <input type="hidden" name="blog_id" value="15063622">
  <input type="hidden" name="source" value="https://learn-powershell.net/2014/06/24/changing-ownership-of-file-or-folder-using-powershell/">
  <input type="hidden" name="sub-type" value="actionbar-follow">
  <input type="hidden" id="_wpnonce" name="_wpnonce" value="e5033639db">
  <div class="actnbr-button-wrap">
    <button type="submit" value="Sign me up"> Sign me up </button>
  </div>
</form>

Text Content

Learn Powershell | Achieve More
What is this Powershell of which you speak?
Skip to content
 * Home
 * About
 * Articles
 * PowerShell Forum Directory
 * Projects
 * Publications
 * Scripts
 * Speaking

← PowerShell User Group in Omaha Nebraska!
Quick Hits: Did I Really Lose My Output With Receive-Job By Not Using–Keep? →


CHANGING OWNERSHIP OF FILE OR FOLDER USING POWERSHELL

Posted on June 24, 2014 by Boe Prox

While working on a project recently, I needed to find an easy way to take
ownership of a profile folder and its subfolders to allow our support staff to
either delete the profile or be able to traverse the folder to help troubleshoot
issues. Typically, one could use Explorer to find the folder and then take
ownership and be done with it. But the goal was to come up with a command line
solution that not only worked quickly, but didn’t miss out on a file or folder.

The brief background on this is that roaming profiles sometimes would become
inaccessible to our support staff in that only the user account and System would
have access to the profile folder and its sub-folders and files. Also, ownership
of those objects were by the user account. This created issues with deleting
accounts and troubleshooting profile related issues.

Before showing the solution that I came up with, I will run down a list of
attempts which never quite met my requirements and why.

Using Takeown.exe

This was actually my initial idea as I allows for recursive actions and lets me
specify to grant ownership to Builtin\Administrators. Sure it wasn’t a
PowerShell approach, but it met the requirements of what I wanted to do…or so I
thought.



The first problem is that it is slow. I kicked it off on my own profile (because
it is always more fun to test on yourself than others) and found that it would
take upwards of 10 minutes vs. the ~2 minute UI approach. Obviously this is an
issue if I expect to have this used as part of my project for others to take
ownership on profiles which would more than likely have more items than my
profile. I still decided to press forward with this and later found the second
issue: takeown.exe would not reliably grant ownership completely down the tree
of subfolders. This was a huge issue and would not be acceptable with the
customer.

Take Ownership using PowerShell and Set-ACL

The next idea was to grab the ACL object of a folder elsewhere in the user’s
home directory that had good permissions and then change the owner in that ACL
object to ‘Builtin\Administrators” and the apply it to the profile folder.

$ACL = Get-ACL .\smithb
$Group = New-Object System.Security.Principal.NTAccount("Builtin", "Administrators")
$ACL.SetOwner($Group)
Set-Acl -Path .\smithb\profile.v2 -AclObject $ACL

Sounds good, right? Well, not really due to some un-foreseen issues. Because the
accounts do not have the proper user rights (seTakeOwnershipPrivilege,
SeRestorePrivilege and SeBackupPrivilege), this would fail right away with an
‘Access Denied’ error. Fine, I can add those privileges if needed and continue
on from there. Well, it doesn’t quite work that way either because only the
directories would propagate these permissions but the files wouldn’t get
ownership.

Set-Owner Function

The final thing that I came up with followed a similar idea as my second
attempt, but makes sure to allow for recursion and files and folders as well as
allowing either ‘Builting\Administrators’ or another account to have ownership
of files and folders. To do this I dove into the Win32 API to first allow the
account to elevate the tokens that I have mentioned before.

Try {
[void][TokenAdjuster]
} Catch {
$AdjustTokenPrivileges = @"
using System;
using System.Runtime.InteropServices;

public class TokenAdjuster
{
    [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
[void][TokenAdjuster]::AddPrivilege("SeRestorePrivilege") #Necessary to set Owner Permissions
[void][TokenAdjuster]::AddPrivilege("SeBackupPrivilege") #Necessary to bypass Traverse Checking
[void][TokenAdjuster]::AddPrivilege("SeTakeOwnershipPrivilege") #Necessary to override FilePermissions

This allows me to traverse the directory tree and set ownership on the files and
folders. If I cannot take ownership on a file or folder (because inheritance is
not allowed from the parent folder), then it moves up a level to grant Full
Control to to parent folder, thus allowing me to take ownership on the folder or
file below it.

Process {
    ForEach ($Item in $Path) {
        Write-Verbose "FullName: $Item"
        #The ACL objects do not like being used more than once, so re-create them on the Process block
        $DirOwner = New-Object System.Security.AccessControl.DirectorySecurity
        $DirOwner.SetOwner([System.Security.Principal.NTAccount]$Account)
        $FileOwner = New-Object System.Security.AccessControl.FileSecurity
        $FileOwner.SetOwner([System.Security.Principal.NTAccount]$Account)
        $DirAdminAcl = New-Object System.Security.AccessControl.DirectorySecurity
        $FileAdminAcl = New-Object System.Security.AccessControl.DirectorySecurity
        $AdminACL = New-Object System.Security.AccessControl.FileSystemAccessRule('Builtin\Administrators','FullControl','ContainerInherit,ObjectInherit','InheritOnly','Allow')
        $FileAdminAcl.AddAccessRule($AdminACL)
        $DirAdminAcl.AddAccessRule($AdminACL)
        Try {
            $Item = Get-Item -LiteralPath $Item -Force -ErrorAction Stop
            If (-NOT $Item.PSIsContainer) {
                If ($PSCmdlet.ShouldProcess($Item, 'Set File Owner')) {
                    Try {
                        $Item.SetAccessControl($FileOwner)
                    } Catch {
                        Write-Warning "Couldn't take ownership of $($Item.FullName)! Taking FullControl of $($Item.Directory.FullName)"
                        $Item.Directory.SetAccessControl($FileAdminAcl)
                        $Item.SetAccessControl($FileOwner)
                    }
                }
            } Else {
                If ($PSCmdlet.ShouldProcess($Item, 'Set Directory Owner')) {                        
                    Try {
                        $Item.SetAccessControl($DirOwner)
                    } Catch {
                        Write-Warning "Couldn't take ownership of $($Item.FullName)! Taking FullControl of $($Item.Parent.FullName)"
                        $Item.Parent.SetAccessControl($DirAdminAcl) 
                        $Item.SetAccessControl($DirOwner)
                    }
                }
                If ($Recurse) {
                    [void]$PSBoundParameters.Remove('FullName')
                    Get-ChildItem $Item -Force | Set-Owner @PSBoundParameters
                }
            }
        } Catch {
            Write-Warning "$($Item): $($_.Exception.Message)"
        }
    }
}
End {  
    #Remove priviledges that had been granted
    [void][TokenAdjuster]::RemovePrivilege("SeRestorePrivilege") 
    [void][TokenAdjuster]::RemovePrivilege("SeBackupPrivilege") 
    [void][TokenAdjuster]::RemovePrivilege("SeTakeOwnershipPrivilege")
}

Using this approach, I was able to accurately take ownership on all of the items
as well as not facing major slowdown (it was roughly 30 seconds slower than the
UI approach). Seemed like a good tradeoff to me.

Here are a couple of examples of the function in action:

Set-Owner -Path .\smithb\profile.v2 -Recurse -Verbose



Set-Owner -Path .\smithb\profile.v2 -Recurse -Verbose -Account 'WIN-AECB72JTEV0\proxb'



The function is available to download from the following link:

http://gallery.technet.microsoft.com/scriptcenter/Set-Owner-ff4db177


SHARE THIS:

 * Twitter
 * Facebook
 * Email
 * LinkedIn
 * Reddit
 * Pocket
 * 


LIKE THIS:

Like Loading...


RELATED

PowerShell Profile Removal GUIOctober 5, 2011In "powershell"

Updated Function to Remove Long Files and DirectoriesJanuary 8, 2016In
"powershell"

Use PowerShell to remove local profilesJanuary 27, 2011In "powershell"

This entry was posted in powershell and tagged owner, Powershell, win32API.
Bookmark the permalink.
← PowerShell User Group in Omaha Nebraska!
Quick Hits: Did I Really Lose My Output With Receive-Job By Not Using–Keep? →


32 RESPONSES TO CHANGING OWNERSHIP OF FILE OR FOLDER USING POWERSHELL

 1.  Ryan B says:
     November 8, 2017 at 9:40 am
     
     I’m happy to report that I had the same issue about nothing happening, but
     after trial-and-error I was able to make it run. First let me say thanks to
     Boe for doing the heavy lifting for the script and also the clear
     explanation.
     
     The syntax that worked for me is:
     . .\Set-Owner.ps1; Set-Owner -Path .\mypath -Recurse -Verbose -Account
     ‘mydomain\myaccount’
     
     In the front, there is a dot and a space before the dot backslash, and a
     semicolon between the ps1 file and the function, specifying which function
     to be executed from that file. I think PowerShell changed over the years
     but the actual code works great.
     
     Before running it, I granted permissions to run the unsigned script with:
     Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
     
     Reply
     
 2.  chad says:
     October 27, 2017 at 5:15 pm
     
     It seems to apply correctly but when I browse the folder it still tells me
     I need READ rights to view it
     
     VERBOSE: FullName: \filersvr01\X$\myuser\Downloads
     VERBOSE: Performing the operation “Set Directory Owner” on target
     “\filersvr01\X$\myuser\Downloads”.
     
     Reply
     
 3.  mgb1979 says:
     September 19, 2016 at 7:05 am
     
     I’m fixing a big problem on an old EMC Celerra share and this saved me a
     lot of time today, a lot of time. I looked at a number of options with
     icacls, takeown and unix command but this work beautifully. Thank you Sir.
     
     Reply
     

 4.  Pingback: Powershell Grant User Access To Folder | Liyongbak

     
 5.  Dan Tenenbaum says:
     March 22, 2016 at 7:59 pm
     
     I’m having the same issue as some others. No output whatsoever, prompt
     comes back right away. Also, I’m not sure if this will do what I really
     want, which is to grant ownership to a different user, one who does not
     have any admin privileges. If not, then I don’t need to bother finding out
     why it’s not working. Thanks!
     
     Reply
     * Patrick Puorro says:
       April 13, 2016 at 12:27 pm
       
       Dan, Did you ever figure out why it just returns to a prompt without
       working? Its doing the same thing for me.
       
       Reply
       * Dan Tenenbaum says:
         April 13, 2016 at 8:43 pm
         
         No, I gave up and found that icacls.exe worked well for me.
         
         Reply
         * Garrett says:
           December 1, 2016 at 1:48 pm
           
           I have the same issue of no output. I have tried the script on
           multiple devices. Anyone have suggestions? I would really love to be
           able to use this script.
           
           Reply
           * Michael L says:
             May 9, 2017 at 4:55 am
             
             Copy the entire contents of Set-Owner.ps1 and paste into your
             Powershell session and hit Enter a couple of times, the Set-Owner
             can be called directly as a known Function in powershell in your
             current session.
             Like others I’m using “\servername\c$\foldername” as -Path
             parameter, it is not always working using c:\foldername, at least
             not with the -Recurse option.
             However, I’m having trouble taking ownership of many files, but
             folders seems på be ok.
             This could be files with broken inheritance in security, I can
             manually fix them, but takes too long.
             But if running Set-Owner script with a User that has elevated
             administrator rights on the server and also has full access to the
             files with broken inheritance, then Set-Owner is able to change the
             owner.
             
             
             
           
         
       
     * rhumborl says:
       October 27, 2017 at 4:54 am
       
       I had the same problem. This is due to how the cmdlet is called, in that
       it is a function inside of a ps1 file. I haven’t worked out how to call
       it directly from teh PS command line, but adding the call to Set-Owner to
       the end of SetOwner.ps1 itself worked.
       
       Set-owner.ps1
       
       Function Set-Owner {
           ....
       }
       
       Set-Owner -Path C:\Path\To\Own -Recurse -Verbose -Account 'MyDomain\MyUser'
       
       
       ** Commad Line **
       
       PS E:\_files\_temp> .\Set-Owner
       
       
       Reply
       
     
 6.  John says:
     December 4, 2015 at 3:58 am
     
     Running the following command results in an exception “The security
     identifier is not allowed to be the owner of this object.”
     
     Set-Owner -Path C:\Script\Share\user -Account ‘domain\user’ -Recurse
     
     Changing the owner manually works.
     
     Any ideas?
     
     Reply
     * Mike says:
       January 4, 2016 at 9:30 am
       
       run you scripts against the UNC path (eg. \servername\share\directory)-
       Something blocks the local drives (eg c:\ or d:)
       
       Reply
       
     

 7.  Pingback: How To Load A Custom Function In PowerShell | Remarqable IT

     
 8.  dgeddings says:
     May 20, 2015 at 1:11 pm
     
     Any way to use this with a source file with the paths in it? I have around
     a thousand separated user home directories I need to fix and I have all the
     paths in a csv/txt file. Once I can repair the permissions I can actually
     do something with all that wasted space.
     Thanks!
     
     Reply
     
 9.  Peter J says:
     April 1, 2015 at 4:25 am
     
     One gotcha is if you are working in the wrong namespace. I couldn’t get
     this to work, getting ‘cannot find path’ even though the path was correct.
     After pulling my hair for a while i noticed the prompt: PS SQLSERVER:>
     A quick set-location C: later everything worked.
     
     Reply
     
 10. adhe says:
     March 24, 2015 at 10:06 am
     
     Is it weird to tell you that I love you? Because, right now, in this moment
     of triumph, I freaking LOVE you.
     
     Client wanted a user added to a share. Easy enough, right? Unless
     inheritance is borked and even our domain admin account can’t see the
     permissions. I tried everything but I was having to go to each and every
     folder and file that was jacked up and do this process:
     
     Properties > Security > Advanced > change ownership to
     Domain\Administrators > OK out > Go back in > continue button > disable
     inheritance > remove permissions > enable inheritance > OK > OK.
     
     And this is a law firm that saves everything and it’s all arranged in
     endless subfolders. So seeing the error list D:\cen….\2013 is NOT helpful
     because I assure you there are 100 folders named 2013. It was horrible. I
     tried just taking ownership of each and then trying to push down but that
     didn’t work.
     
     Finally, after 2 hours, I looked for a script again and found this. At
     first all the code made my eyes cross but I’m glad you had it for download.
     I just had to change your “Builtin” to their domain name, run it, and less
     than a second later, everything was working. I changed the parent folder’s
     permissions, got NO error messages, and I can confirm that all of the
     subfolders and files have the right ownership and permissions.
     
     Reply
     * Boe Prox says:
       March 24, 2015 at 9:10 pm
       
       Lol! I appreciate your awesome comment! Also glad that my script was able
       to help you out with your issue.
       
       Reply
       
     * JJ says:
       December 9, 2015 at 9:07 am
       
       Magnificent use of the word ‘borked’, too. Well played. Well played.
       
       Reply
       
     
 11. mahesh1000h says:
     December 12, 2014 at 9:38 am
     
     Thanks for nice post and script
     I am trying your script on 2008 R2 PowerShell admin console
     However nothing is happening, I am not getting any error neither message
     and also nothing is happening to directories
     Not sure where to look for
     OR
     Am I missing any basic step?
     I have done ExecutionPolicy to un restricted
     Any help is highly appreciated please
     
     Thanks
     Mahesh
     
     Reply
     
 12. Matt Maguire says:
     November 4, 2014 at 3:48 pm
     
     Just tried using your function, but didn’t get anywhere. The server in
     questions is 2008 R2 running PowerShell 3.0. Do I need PowerShell 4 to get
     this to work? Thanks!
     
     Reply
     * Matt Maguire says:
       November 4, 2014 at 3:54 pm
       
       More specifically, after adding the function to my System32 directory I
       ran ” set-owner.ps1 -path .\userprofile.V2 -recurse -verbose -account
       ‘domain\myusername'” under the domain admin account. There was no output,
       just a new Prompt. After logging in as myself to the server and trying to
       pen the folder, I found I could not browse or take ownership of the file.
       I presume I left out a necessary step or two. Any thoughts? Thanks!
       
       Reply
       * DM says:
         November 12, 2014 at 10:31 am
         
         Same thing. Were you able to find a solution?
         
         Reply
         
       
     
 13. f1refoxy says:
     October 7, 2014 at 7:09 am
     
     hello,
     Thanks for this Post!
     for my needs, I’m happy with the takeown.exe solution for that problem.
     I want to share my script – it changes all folder (testfolders) und
     subfolders owners to the “Adminisrators” Group.
     
     Get-ChildItem E:\testfolders |Where-Object {$.PSIsContainer -eq $true} |
     ForEach-Object {$workpath = $.FullName;Invoke-Expression -Command
     ‘takeown.exe /F “$workpath” /A /r /D N’ }
     
     Reply
     
 14. DarkLite1 says:
     September 8, 2014 at 2:22 am
     
     Thank you Boe, great function! I left a question on the Microsoft
     Scriptcenter, as I’m having some difficulties with the ‘-Recurse’ option
     for regular users.
     
     Reply
     * DarkLite1 says:
       September 8, 2014 at 2:53 am
       
       Strangely, after Googling around it seems the function is working
       perfectly fine when using UNC-patsh, but not with local paths when you
       want to assign a non-priviliged account. So for now, I use the workaround
       to use the full UNC-path as described here:
       http://fixingitpro.com/2011/07/08/set-owner-with-powershell-%E2%80%9Cthe-security-identifier-is-not-allowed-to-be-the-owner-of-this-object%E2%80%9D/
       
       Reply
       
     
 15. Johnny says:
     August 17, 2014 at 10:45 pm
     
     Great script, just one question: how can I write the verbose output to log
     file?
     
     Reply
     * Boe Prox says:
       August 20, 2014 at 9:05 am
       
       Assuming you are running V3+, you can redirect the verbose stream to a
       file using 4>>
       
       Set-Owner -Verbose 4>> Verbose.txt
       
       Reply
       
     
 16. Keith Wade says:
     July 10, 2014 at 4:38 pm
     
     I tried running your script on our system today and it said “Unable to find
     type [TokenAdjuster]. Make sure that the assembly that contains this type
     is loaded.”
     
     Any ideas as to why this would happen?
     
     Reply
     * Boe Prox says:
       July 10, 2014 at 9:12 pm
       
       Hmm.. I am not sure as it should attempt to load the type and if it
       fails, then it will compile the C# code that contains the type. I won’t
       be able to do much investigating for a week or so but can take a look at
       it when I am available. Until then, have you tried to run through the
       code in chunks to make sure it is working properly?
       
       Reply
       * Keith Wade says:
         July 11, 2014 at 9:31 am
         
         I’m not quite sure that I ran your code the right way. Anyways, we just
         got Icacls working to do our ownership changes instead.
         
         Reply
         
       
     
 17. Randal Hicks (@RandaL_Hicks) says:
     June 26, 2014 at 6:23 pm
     
     An opportunity presented itself to test your script out
     
     Reply
     * Boe Prox says:
       June 26, 2014 at 8:37 pm
       
       Awesome! Hopefully it worked out great for you!
       
       Reply
       
     


LEAVE A REPLY CANCEL REPLY

Fill in your details below or click an icon to log in:

 * 
 * 
 * 
 * 

Email (required) (Address never made public)

Name (required)

Website


You are commenting using your WordPress.com account. ( Log Out /  Change )

You are commenting using your Twitter account. ( Log Out /  Change )

You are commenting using your Facebook account. ( Log Out /  Change )

Cancel

Connecting to %s

Notify me of new comments via email.

Notify me of new posts via email.





Δ




 * BOOKS


 * TRANSLATE THIS BLOG
   
   Translate this blog into different languages...
   
   العربية
   Български
   中文(简体)
   中文(繁體)
   Hrvatski
   Česky
   Dansk
   Nederlands
   Suomi
   Français
   Deutsch
   Ελληνική
   हिन्दी
   Italiano
   日本語
   한국어
   Norsk
   Polski
   Português
   Română
   Русский
   Español
   Svenska
 * Search for:


 * RECENT POSTS
   
   * Dealing with Runspacepool Variable Scope Creep in PowerShell
   * 2018 PowerShell Resolutions
   * Quick Hits: Getting the Local Computer Name
   * Recent Articles on MCPMag
   * Quick Hits: Finding all Hyperlinks in an Excel Workbook


 * TOP POSTS
   
   * Changing Ownership of File or Folder Using PowerShell
   * Starting,Stopping and Restarting Remote Services with PowerShell
   * Querying UDP Ports with PowerShell
   * Avoiding System.Object[] (or Similar Output) when using Export-Csv
   * Building a Chart Using PowerShell and Chart Controls
   * Locating Mount Points Using PowerShell
   * Quick Hits: Finding Exception Types with PowerShell
   * Setting up Local Administrator Password Solution (LAPS)
   * Using PowerShell to Query Web Site Information
   * PowerShell and Excel: Adding Some Formatting To Your Report


 * ARCHIVES
   
   Archives Select Month January 2018  (1) December 2017  (1) September 2017
    (1) July 2017  (2) May 2017  (2) April 2017  (1) February 2017  (2) January
   2017  (1) December 2016  (2) November 2016  (2) October 2016  (2) September
   2016  (2) August 2016  (3) July 2016  (2) June 2016  (2) May 2016  (2) April
   2016  (3) March 2016  (3) February 2016  (2) January 2016  (3) December 2015
    (3) November 2015  (3) October 2015  (5) September 2015  (3) August 2015
    (3) July 2015  (2) June 2015  (3) May 2015  (4) April 2015  (3) March 2015
    (5) February 2015  (4) January 2015  (3) December 2014  (4) November 2014
    (4) October 2014  (4) September 2014  (4) August 2014  (5) July 2014  (2)
   June 2014  (5) May 2014  (4) April 2014  (6) March 2014  (5) February 2014
    (3) January 2014  (7) December 2013  (6) November 2013  (3) October 2013
    (9) September 2013  (6) August 2013  (7) July 2013  (8) June 2013  (4) May
   2013  (9) April 2013  (12) March 2013  (5) February 2013  (7) January 2013
    (7) December 2012  (7) November 2012  (6) October 2012  (5) September 2012
    (2) August 2012  (6) July 2012  (2) June 2012  (7) May 2012  (4) April 2012
    (8) March 2012  (10) February 2012  (2) January 2012  (5) December 2011  (2)
   November 2011  (1) October 2011  (2) September 2011  (6) August 2011  (4)
   July 2011  (3) June 2011  (4) May 2011  (4) April 2011  (1) March 2011  (4)
   February 2011  (8) January 2011  (6) November 2010  (3) October 2010  (5)
   September 2010  (5) August 2010  (7)


 * CATEGORIES
   
   Categories Select Category 2013 Scripting Games Judges Notes Debug Deep Dive
   Excel GUI Modules News Office PowerCLI powershell Scripting Games 2011
   Scripting Games 2012 Scripting Games 2013 scripts SQL Tech-Ed Tips
   Uncategorized V3 V4 V5 VMWare Winter Scripting Games 2014 WPF WSUS

 * * .net
   * api
   * array
   * background jobs
   * binary
   * book
   * c#
   * clock
   * codeplex
   * com object
   * convert
   * CTP
   * database
   * deep dive
   * excel
   * Favorites
   * function
   * groups
   * guest blog
   * hash table
   * Internet Explorer
   * ise
   * mcpmag
   * module
   * MVP
   * network
   * news
   * parameter
   * patches
   * performance
   * pinvoke
   * podcast
   * port
   * PoshChat
   * poshpaig
   * PoshRSJob
   * poshwsus
   * powercli
   * powerscripting
   * Powershell
   * printers
   * quickhits
   * reflection
   * regex
   * registry
   * Regular Expressions
   * report
   * resolution
   * runspace
   * runspaces
   * scripting games 2012
   * scripting games 2013
   * scripting guy
   * scripts
   * SMO
   * Speaker
   * speaking
   * SQL
   * tcp
   * tips
   * tsql
   * updates
   * user group
   * V3
   * V4
   * v5
   * weather
   * widget
   * win32API
   * winter scriting games 2014
   * wmi
   * word
   * WPF
   * wsus
   * xaml


 * EMAIL SUBSCRIPTION
   
   Enter your email address to subscribe to this blog and receive notifications
   of new posts by email.
   
   Email Address:
   
   Sign me up!
   
   Join 479 other subscribers


 * LATEST TECHNET ACTIVITY
   
   * Contributed a helpful post to the Using start-job -scriptblock to run
     script; need help using parameters thread in the The Official Scripting
     Guys Forum! Forum.
   * Contributed a helpful post to the Script to set the Primary DNS Suffix
     thread in the The Official Scripting Guys Forum! Forum.


 * BLOG STATS
   
   * 5,237,684 Visitors Since August 5, 2010


 * META
   
   * Register
   * Log in
   * Entries feed
   * Comments feed
   * WordPress.com

 * 

Learn Powershell | Achieve More
Blog at WordPress.com.

 * Follow Following
    * Learn Powershell | Achieve More
      Join 479 other followers
      
      Sign me up
    * Already have a WordPress.com account? Log in now.

 *  * Learn Powershell | Achieve More
    * Customize
    * Follow Following
    * Sign up
    * Log in
    * Copy shortlink
    * Report this content
    * View post in Reader
    * Manage subscriptions
    * Collapse this bar

%d bloggers like this: