1

What am I trying to do?

Hi! I am writing a script that can accept 2 parameters, ComputerName and CheckWhatFile. The script will then access the computer (file server) specified by ComputerName and look for open file handles of CheckWhatFile.

The problem is the script needs to be executed by an administrative user. Our admins login as a non-privileged account. I want it to be as simple as clicking to run the script and only being prompted for the Get-Credentials box to enter there privileged account. I cannot use Invoke-Command unless you can find a way for it to not require having remote management turned on. The code below works when executed from a privileged PowerShell prompt that is started with runas /user: powershell.exe.

What I need help with

Help me find how to execute the 2 lines of code starting with netfile as a different user.

My code is:

param([string]$ComputerName = $null,[string]$CheckWhatFile = $null)
Import-Module ActiveDirectory

$Credentials = Get-Credential #Get Powerful Credentials

$netfile = [ADSI]"WinNT://$ComputerName/LanmanServer"
$netfile.Invoke("Resources") | foreach {
   try
   {
       $Id = $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)
       $ItemPath = $_.GetType().InvokeMember("Path", 'GetProperty', $null, $_, $null)
       $UserName = $_.GetType().InvokeMember("User", 'GetProperty', $null, $_, $null)
       $LockCount = $_.GetType().InvokeMember("LockCount", 'GetProperty', $null, $_, $null)

       if($ItemPath -eq $CheckWhatFile)
       {
            $Culprit = Get-ADUser -Filter {SamAccountName -eq $UserName} -Credential $Credentials
            Write-Host -ForegroundColor White -NoNewLine "Go Find "
            Write-Host -ForegroundColor Yellow -NoNewLine $Culprit.Name
            Write-Host -ForegroundColor White " and tell them to close the file!"
        }
    }
    catch
    {
    }
 }

Notes:

I have seen some examples with executing ADSI provider queries as a different user but they all relate to LDAP based queries not WinNT.

Mr. Lost IT Guy
  • 137
  • 2
  • 12
  • Using `try..catch` is pointless when you're not handling the caught errors. Just set `$ErrorActionPreference = "SilentlyContinue"` if you want the script to continue no matter what. – Ansgar Wiechers Dec 08 '13 at 11:22

2 Answers2

0

As it stands, the only way you're going to be able to do that is to have them RDP to the file server using the Admin credentials and run the script there. That's the only way they're going to get a powershell console to be able to see that output. Without powershell remoting enabled you can only get a local session, and that means either a local logon or RDP.

mjolinor
  • 66,130
  • 7
  • 114
  • 135
  • I appreciate your feedback. I can confirm it does work when you launch powershell.exe with the command: runas /user:\ powershell.exe – Mr. Lost IT Guy Dec 06 '13 at 22:33
  • Yes, that will work. but it's not going to get the user the output in a PS console. You can re-write it to output to a file, and then read the file back when it's done. – mjolinor Dec 06 '13 at 22:37
  • I should clarify in my use case it is meant to be ran interactively. I am seeking writing the ADSI provider portion to allow direct execution through a low privilege powershell session my admins will have open. – Mr. Lost IT Guy Dec 06 '13 at 22:47
  • From a security standpoint, you'd be better off enabling remoting and using a constrained remote session that delegates the admin credentials. Then you don't hve to give them the admin credentials, and you can limit what they can do in the session to only what you they need to do their job. – mjolinor Dec 06 '13 at 22:52
  • Do you have documentation you could point me to on locking down the ws-remotemanagement service or should I google away? – Mr. Lost IT Guy Dec 06 '13 at 22:54
  • http://automatewithpowershell.wordpress.com/2012/11/27/delegated-administration-in-windows-powershell-v3/ – mjolinor Dec 06 '13 at 23:05
0

Something like this might work:

$provider = "WinNT://$ComputerName/LanmanServer"
$cred     = Get-Credential

$netfile  = New-Object DirectoryServices.DirectoryEntry(
              $provider, $cred.UserName, $cred.GetNetworkCredential().Password
            )
$netfile.Invoke("Resources") | % {
  ...
}
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • I ran this and it failed on the line: $netfile.Invoke("Resources" | % { With the error of: The following exception occurred while retrieving member "Invoke": "The group name could not be found. – Mr. Lost IT Guy Dec 06 '13 at 22:25
  • @Mr.LostITGuy Then the account whose credentials you provided doesn't have admin privileges on the remote host. – Ansgar Wiechers Dec 07 '13 at 14:06
  • @AnsgarWiechers: I also have the problem with "The group name...". My user is in the local admin group and is a domain admin. – flayn Feb 11 '14 at 11:54