[英]Trouble calling powershell script from within powershell with arguments
I have spent the last 4 hours on this issue and would greatly appreciate any input you might have. 我在此问题上花了最后4个小时,非常感谢您提供的任何信息。
I need to call a powershell script with different credentials and pass arguments onto that script. 我需要使用不同的凭据调用powershell脚本,并将参数传递给该脚本。 Following the installation of a program wrapped in WISEScript this script kicks off to gather AD accounts for the machine and remove them from specific AD Security Groups.
安装以WISEScript包装的程序之后,该脚本将启动以收集计算机的AD帐户并将其从特定的AD安全组中删除。 Unfortunately as the script runs locally I cannot use ActiveDirectory modules in powershell as not all machines in our environment have RSAT.
不幸的是,由于脚本在本地运行,因此无法在Powershell中使用ActiveDirectory模块,因为我们环境中的并非所有计算机都具有RSAT。 The initial script is run from an elevated account on the machine:
初始脚本从计算机上的提升帐户运行:
$creds = New-Object System.Management.Automation.PsCredential("DOMAIN\USER", (ConvertTo-SecureString "Password" -AsPlainText -Force))
$ProfileGUIDS = Get-ChildItem 'hklm:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileGuid'
$Groups = [ADSI]"LDAP://CN=Group4d_test,OU=GroupMigrationTesting,OU=TestOU,OU=US,DC=DOMAIN",[ADSI]"LDAP://CN=Group3d_test,OU=GroupMigrationTesting,OU=TestOU,OU=US,DC=DOMAIN"
Function Get-DistinguishedName ($strUserName)
{
$searcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]'')
$searcher.Filter = "(&(objectClass=User)(samAccountName=$strUserName))"
$result = $searcher.FindOne()
if ($result)
{
Return $result.GetDirectoryEntry().DistinguishedName
}
}
forEach ($GUIDkey in $ProfileGUIDS)
{
$GUID = Out-String -InputObject $GUIDKey
$index = $GUID.IndexOf("S-1")
$GUID = $GUID.Substring($index)
$GUID = $GUID.Substring(0,128)
$index = $GUID.IndexOf(" ")
$GUID = $GUID.Substring(0,$index)
$Profile = "hklm:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$GUID"
$ProfileItems = Get-ItemProperty $Profile
$SAM = $ProfileItems.ProfileImagePath
$index = $SAM.LastIndexOf("\")
$index ++
$SAM = $SAM.substring($index)
$UserDN = Get-DistinguishedName $SAM
$User = [ADSI]"LDAP://$UserDN"
if($User -ne $null)
{
forEach($group in $groups)
{
Right here is where I need to call the 2nd script with different credentials. 在这里,我需要使用不同的凭据调用第二个脚本。
This is RemoveUsers.ps1, the script I need to run with different credentials: 这是RemoveUsers.ps1,我需要使用不同的凭据运行脚本:
param
(
[string]$group = "MyDefaultSAM",
[string]$user = "MyDefaultUser"
)
$Group.remove($User.ADsPath)
I have tried: 我努力了:
start-process powershell.exe -Credential $creds -NoNewWindow -ArgumentList "Start-Process $PSSCriptRoot\RemoveUsers.ps1 -Verb
This will run the script however I cannot specify any arguments 这将运行脚本,但是我无法指定任何参数
powershell.exe -file "$PSScriptRoot\RemoveUsers.ps1" -user $user -group $group
This calls the script with arguments but does not allow for the -Credentials switch 这使用参数调用脚本,但不允许使用-Credentials开关
I have also tried: 我也尝试过:
$job = Start-Job -ScriptBlock {
powershell.exe -file "$PSScriptRoot\RemoveUsers.ps1" -user $user -group $group
} -Credential $creds
This runs but does not appear to work properly as the users remain in the AD groups. 它可以运行,但由于用户仍留在AD组中而无法正常工作。
Any help is appreciated. 任何帮助表示赞赏。
Thanks - Jeff 谢谢-杰夫
**** UPDATE **** Thanks for the information. ****更新****感谢您提供信息。 When I add the changes you suggest I receive an error
当我添加更改时,您建议我收到错误消息
Invoke-Command : Parameter set cannot be resolved using the specified named parameters
It appears, as I have found online, the -Credential switch cannot be used without the -Computer switch. 正如我在网上发现的那样,如果没有-Computer开关,就无法使用-Credential开关。 If I specify $env:COMPUTERNAME or localhost for the computer I receive the error
如果我为计算机指定$ env:COMPUTERNAME或localhost,则会收到错误消息
\RemoveUsers.ps1 is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again
I can avoid this issue if I remove the -Credential switch and open the AD group to everyone. 如果删除-Credential开关并向所有人打开AD组,则可以避免此问题。 At this point I don't need to elevate a new powershell script and can add the command in the same.
在这一点上,我不需要提升新的powershell脚本,也可以在其中添加命令。 If I cannot resolve the issue with Invoke-Command this is likely what I will do.
如果我无法使用Invoke-Command解决问题,则可能是我会做的。
**** UPDATE **** What I ultimately had to do was use -Authentication Credssp in the argument list as there is an issue with using the AD Module via Invoke-Command. ****更新****我最终要做的是在参数列表中使用-Authentication Credssp,因为通过Invoke-Command使用AD模块存在问题。 In addition I had to start the Win-RM service, Enable WSMacCredSSP (-role client on each machine and add a DelegateComputer entry and -role server on the server connecting to).
此外,我还必须启动Win-RM服务,启用WSMacCredSSP(每台计算机上的-role客户端并在连接到的服务器上添加DelegateComputer条目和-role服务器)。 Only after the service was started and an entry was made for WSManCredSSP was I able to use the Invoke-Command switch and have the AD Module work correctly.
只有在启动服务并为WSManCredSSP进行了输入之后,我才能够使用Invoke-Command开关并使AD模块正常工作。
This of course makes things more complicated and I decided just installing the AD Module on each PC (after finding a way to do it without RSAT) and forgetting about running the command remotely all together. 当然,这使事情变得更加复杂,我决定只在每台PC上安装AD模块(在找到一种无需RSAT的方法之后),而不必再一起远程运行命令。 Thanks for your help with the matter.
感谢您的协助。 Thanks
谢谢
You don't need to run PowerShell scripts with powershell.exe
when calling them from another PowerShell script. 从另一个PowerShell脚本调用它们时,不需要使用
powershell.exe
运行PowerShell脚本。 Simply use the call operator ( &
). 只需使用呼叫运算符(
&
)。 Also, I'd use Invoke-Command
for running something inline with different credentials. 另外,我将使用
Invoke-Command
运行具有不同凭据的内联Invoke-Command
。
Beware that the scriptblock doesn't automatically know about the variables in the rest of your script. 请注意,脚本块不会自动了解其余脚本中的变量。 You need to pass them into the scriptblock via the
-ArgumentList
parameter. 您需要通过
-ArgumentList
参数将它们传递到脚本块中。 That is most likely the reason why removal didn't work when you ran RemoveUsers.ps1
as a job. 这很可能是您将
RemoveUsers.ps1
作为作业运行时,无法删除的原因。
Something like this should work: 这样的事情应该起作用:
Invoke-Command -ScriptBlock {
& "$PSScriptRoot\RemoveUsers.ps1" -user $args[0] -group $args[1]
} -ArgumentList $user, $group -Credential $creds -Computer $env:COMPUTERNAME
This requires PSRemoting, though (run Enable-PSRemoting
as an administrator). 不过,这需要PSRemoting(以管理员身份运行
Enable-PSRemoting
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.