0

私は2つの動作中のpowershellスクリプトを持っています。次のように script1.ps1 を呼び出します。

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

そして、スクリプトは を返すはずuserId=DOMAIN/UserIdです。最初のスクリプト:

#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 

そして、これは全体の動作中の 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("\","/") 

これが私の問題です。ドメイン内のほとんどの IP アドレスでは、次のものが返されます。

Get-WmiObject : アクセスが拒否されました。(HRESULT からの例外: 0x80070005 (E_ACCESS DENIED))

これを調査したところ、 「get-wmiobject win32_process -computername」で「アクセスが拒否されました、コード 0x80070005」というエラーが発生し、昇格したアカウントにドメイン全体で WMI を実行する権限を与えることをお勧めします。

そして、この記事http://technet.microsoft.com/en-us/library/cc787533(v=ws.10).aspxでその方法が説明されています。

しかし、ドメインを担当するチームに、この昇格されたアカウントに WMI アクセス許可を付与するよう説得するのは至難の業です。また、スクリプトは、ドメイン内の一部の IP アドレスの UserId を返すことができます。

これを解決する別の方法はありますか?グーグルで何を調べればいいですか?

4

1 に答える 1

1

Invoke-Commandを使用し、 PowerShell Remotingを使用して script2 をリモートで実行することを検討しましたか?

別の資格情報を使用してリモート スクリプトを実行することもできます。セキュリティ チームを説得して、WMI ではなく PowerShell Remoting を有効にすることをお勧めします。invoke-command を介して実行された場合の wmi クエリは、マシンに対してローカルになるため、機能する可能性が高くなり、標準出力バッファーを読み取る必要もなくなります。

開始するには、 Enter-PSSessionを試してください。これにより、環境で PS Remoting を機能させるために必要な作業量をすばやく判断できます。

将来、多くのコンピューターを同時にターゲットにしたいと思うかもしれません。その場合、PS Remoting とStart-Jobが役に立ちます。

于 2013-09-03T15:01:28.620 に答える