nathansclone4
nathansclone4

Reputation: 101

How do I run Get-ChildItems on a UNC path with different elevated credentials

I have a script (below) that checks how much data a user has saved in a directory - this example uses their roaming profile but it should work on any directory. The script originally used the UNC path directly in the Get-ChildItems command. This worked fine when the script was run using the admin account (as expected). So that I didn't have to use the admin account to run the script I added in the New-PSDrive code so I can pass in the admin credentials. This code again worked fine if I ran it as an admin account. this code is below:

$username = "test_username"
$domian_user = "DOMAINNAME\${username}"

$directory = "\\server_name\profiles$\${username}.V6\" 

# map a network drive "
Remove-PSDrive -Name temp -ErrorAction SilentlyContinue
New-PSDrive -Name temp -PSProvider FileSystem -Root $directory | Out-Null

if (-Not (Test-Path -Path "temp:\")) {
    Write-Host "ERROR: Directory not found - ""temp:\""" -ForegroundColor Red
} else {
    # get a list of all files in the $directory folder structure. select the full "file path, owner, file size
    $file_list = Get-ChildItem -Path "temp:\" -Recurse -Force -File | Select-Object Fullname, @{Name='Owner'; Expression={ $_.GetAccessControl().Owner }}, @{Name="Bytes"; Expression={ "{0:N0}" -f $_.Length }}, LastAccessTime, LastWriteTime, CreationTime
    $file_list = $file_list | Where-Object {$_.Owner -eq $domian_user} 
    $total_size = ($file_list | Measure-Object -Sum Bytes).Sum
    
    # update our output ojbect
    $size_MB = "{0:n3}" -f ($total_size / 1MB)

    Write-Host $directory
    Write-Host "   MB:" $size_MB
}

# removed the mapped drive
Remove-PSDrive -Name temp -ErrorAction SilentlyContinue

This worked if I ran it as admin so the next step was to use credentials with the New-PSDrive. The changes I made to use credentials are as follows:

...
# New-PSDrive -Name temp -PSProvider FileSystem -Root $directory | Out-Null

$adm_credentials = Get-Credential -Credential "DOMAINNAME\adm_username"
New-PSDrive -Name temp -PSProvider FileSystem -Root $directory -Credential $adm_credentials | Out-Null
...

But this gives an error:

New-PSDrive : The network path was not found
At D:\scripts\test.ps1:13 char:1
+ New-PSDrive -Name temp -PSProvider FileSystem -Root $directory -Crede ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (temp:PSDriveInfo) [New-PSDrive], Win32Exception
    + FullyQualifiedErrorId : CouldNotMapNetworkDrive,Microsoft.PowerShell.Commands.NewPSDriveCommand

I assume it is to do with my user not having access to the path I am trying to map (which is why I am using the New-PSDrive with credentials in the first place).

How do I run Get-ChildItems on a UNC path with elevated credentials?

I am using powershell version: 5.1.17763.1007

Thanks

Upvotes: 1

Views: 1363

Answers (1)

nathansclone4
nathansclone4

Reputation: 101

I came up with a solution/work around that works for me.

I put the below script in a file. I changed it back to using UNC paths and added some params so I can pass in values:

param (
    [Parameter(Mandatory=$true)][String]$Username,
    [String]$Path = ""
)

$domian_user = "DOMAINNAME\${Username}"
if ($Path -eq "") {
    $Path = "\\server_name\profiles$\${Username}.V6\" 
}

if (-Not (Test-Path -Path $Path)) {
    Write-Host ""
    Write-Host "ERROR: Directory not found" -ForegroundColor Red
} else {
    # get a list of all files if the $Path folder structure
    # and select the full file name, owner, size
    $file_list = Get-ChildItem $Path -Recurse -Force -File | Select-Object Fullname, @{Name='Owner'; Expression={ $_.GetAccessControl().Owner }}, @{Name="Bytes"; Expression={ "{0:N0}" -f $_.Length }}, LastAccessTime, LastWriteTime, CreationTime
    $file_list = $file_list | Where-Object {$_.Owner -eq $domian_user} 
    $total_size = ($file_list | Measure-Object -Sum Bytes).Sum
    
    $size_MB = "{0:n3}" -f ($total_size / 1MB)

    Write-Host $Path 
    Write-Host "   MB: ${size_MB}"
}

# keep the window open
Read-Host "Press [Enter] to close this window"

I changed the original script to use the below code. This opens a new powershell window/process with the admin credentials and runs the command there. I can't get data back from the script but I can work with that.

 $adm_credentials = Get-Credential -Credential "DOMAINNAME\adm_username"
 $username = "test_username"
 Start-Process powershell.exe -Credential $adm_credentials -ArgumentList "-file D:\scripts\UserDataAllocation2.ps1", "-user ${username}"

Upvotes: 1

Related Questions