0
votes

I have two working powershell scripts. You would invoke script1.ps1 with:

.\script1.ps1 "sender-ip=10.10.10.10"

And the script is supposed to return userId=DOMAIN/UserId. The first script:

#script1.ps1

$abc = $args
$startInfo = $NULL
$process = $NULL
$standardOut = $NULL

<#Previously created password file in C:\Script\cred.txt, read-host -assecurestring | convertfrom-securestring | out-file C:\Script\cred.txt#>
$password = get-content C:\Script\cred.txt | convertto-securestring

$startInfo = New-Object System.Diagnostics.ProcessStartInfo
$startInfo.FileName = "powershell.exe"
$startInfo.Arguments = "C:\script\script2.ps1 " + $abc

$startInfo.RedirectStandardOutput = $true
$startInfo.UseShellExecute = $false
$startInfo.CreateNoWindow = $false
$startInfo.Username = "Username"
$startInfo.Domain = "DOMAIN"
$startInfo.Password = $password 

$process = New-Object System.Diagnostics.Process
$process.StartInfo = $startInfo
$process.Start() | Out-Null
$standardOut = $process.StandardOutput.ReadToEnd()
$process.WaitForExit()

# $standardOut should contain the results of "C:\script\script1.ps1"
$standardOut 

And this is the entire working script2.ps1

#script2.ps1

$line_array = @()
$multi_array = @()
[hashtable]$my_hash = @{}
$Sender_IP = $NULL
$Win32OS = $NULL
$Build = $NULL
$LastUser = $NULL
$UserSID = $NULL
$userID=$NULL
$output = $NULL


foreach ($i in $args){
   $line_array+= $i.split(" ")
}

foreach ($j in $line_array){
    $multi_array += ,@($j.split("="))
}

foreach ($k in $multi_array){
    $my_hash.add($k[0],$k[1])
}

$Sender_IP = $my_hash.Get_Item("sender-ip")


<#Gather information on the computer corresponding to $Sender_IP#>

$Win32OS = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $Sender_IP 


<#Determine the build number#>
$Build = $Win32OS.BuildNumber


<#Running Windows Vista with SP1 and later, i.e. $Build is greater than or equal to 6001#>
if($Build -ge 6001){
    $Win32User = Get-WmiObject -Class Win32_UserProfile -ComputerName $Sender_IP
    $Win32User = $Win32User | Sort-Object -Property LastUseTime -Descending
    $LastUser = $Win32User | Select-Object -First 1
    $UserSID = New-Object System.Security.Principal.SecurityIdentifier($LastUser.SID)
    $userId = $UserSID.Translate([System.Security.Principal.NTAccount])
    $userId = $userId.Value
}


<#Running Windows Vista without SP1 and earlier, i.e $Build is less than or equal to 6000#>
elseif ($Build -le 6000){
    $SysDrv = $Win32OS.SystemDrive
    $SysDrv = $SysDrv.Replace(":","$")
    $ProfDrv = "\\" + $Sender_IP + "\" + $SysDrv
    $ProfLoc = Join-Path -Path $ProfDrv -ChildPath "Documents and Settings"
    $Profiles = Get-ChildItem -Path $ProfLoc
    $LastProf = $Profiles | ForEach-Object -Process {$_.GetFiles("ntuser.dat.LOG")}
    $LastProf = $LastProf | Sort-Object -Property LastWriteTime -Descending | Select-Object -First 1
    $userId = $LastProf.DirectoryName.Replace("$ProfLoc","").Trim("\").ToUpper()
}

else{
    $userId = "Unknown/UserID"
}

if ($userId -ne $NULL){
    $output = "userId=" + $userId
}
elseif ($userID -eq $NULL)
{
    $userId = "Unknown/UserID"
    $output = "userId=" + $userId
}


$output.replace("\","/") 

Here is my problem. On most IP addresses in our domain, it returns:

Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESS DENIED))

I researched this, and "get-wmiobject win32_process -computername" gets error "Access denied , code 0x80070005" recommends giving the elevated account permission to run WMI throughout the Domain.

And this article, http://technet.microsoft.com/en-us/library/cc787533(v=ws.10).aspx explains how to do it.

But convincing the team that is in charge of the domain to grant WMI permissions to this elevated account will be a stretch. And, the script is able to return the UserId for some of the IP addresses in the domain.

Is there another way to resolve this? What should I research on google?

1

1 Answers

1
votes

Have you considered using Invoke-Command and executing your script2 remotely using PowerShell Remoting?

Your remote script can the be executed using alternative credentials, you may have better luck convincing your security team to enable PowerShell Remoting rather than WMI. Your wmi queries when run via invoke-command will be local to the machine so will have a better chance of working, it also avoids the need to read the standard-out buffer.

To get you started, try Enter-PSSession as this will enable you to quickly determine how much work is necessary to get PS Remoting working in your environment.

In the future you might want to target many computers simultaneously, in which case PS Remoting and Start-Job would be helpful.