【问题标题】:PowerShell launch script in new instance新实例中的 PowerShell 启动脚本
【发布时间】:2014-04-23 07:18:43
【问题描述】:

我有一个主脚本,它有几个选项。当您在菜单中选择 1 时,将执行操作 1,然后您将返回菜单。这工作正常,但我希望能够选择例如 8,它在新的 PowerShell 窗口中启动 Permissions 脚本 的代码块。我想将所有代码都放在一个脚本中,而不是调用另一个脚本。

我知道这可以通过在多个威胁中发现的“Start-Process powershell”来完成。这确实会打开一个新的 PowerShell 窗口,但不会正确执行 Permissions 脚本 的代码块。任何帮助将不胜感激。

主脚本:

<# Author: Me #>
# Variables
$User = [Environment]::UserName
$OutputPath = "C:\Users\$User\Downloads\"
# Functions
Function Manager ($u) { 
$m = Get-ADObject -Identity $u.managedBy -Properties displayName,cn
    if($m.ObjectClass -eq "user") { $m.displayName } Else{ $m.cn } } 
# Hit play
do {
  [int]$userMenuChoice = 0
  cls
  while ( $userMenuChoice -lt 1 -or $userMenuChoice -gt 7) {
    Write-Host "PowerShell for dummies"
    Write-Host "__________________________________________________"
    Write-Host "1. Groups created in the last 3 weeks"
    Write-Host "2. Users created in the last 3 weeks"
    Write-Host "3. All BEL Users"
    Write-Host "4. Users with an incorrect display name or city"
    Write-Host "5. Users de-provisioned within 3 weeks"
    Write-Host "6. Files/Folders: Activate inheritance & set owner to admin"
    Write-Host "7. Quit"

    [int]$userMenuChoice = Read-Host "Please choose an option"

    switch ($userMenuChoice) {
      1{# Groups created in the last 3 weeks
        $When = ((Get-Date).AddDays(-21)).Date 
        Get-ADGroup -SearchBase "OU=Groups,OU=BEL,OU=EU,DC=domain,DC=net" -Filter {whenCreated -ge $When} -Properties * | 
        Select whenCreated, cn, displayName, GroupScope, GroupCategory, description, info, @{Label="Managed By"; expression= { Manager $_ } } | Export-Csv $OutputPath"New groups.csv" -NoTypeInformation -Delimiter ";" -Encoding utf8; start $OutputPath"New groups.csv"}
      2{# Users created in the last 3 weeks
        $When = ((Get-Date).AddDays(-21)).Date
        Get-ADUser -SearchBase "OU=BEL,OU=EU,DC=domain,DC=net" -Filter {whenCreated -ge $When} -Properties * | Select whenCreated, Name,displayName, sn,  givenName, sAMAccountName, title, description, employeeType, info, department, company, homeDirectory, scriptPath, physicalDeliveryOfficeName, @{Label="Managed By"; expression= { Manager $_ } } | Export-Csv $OutputPath"New users.csv" -NoTypeInformation -Delimiter ";" -Encoding utf8; start $OutputPath"New users.csv"}
      3{# All BEL users
        Get-ADUser -SearchBase "OU=Users,OU=BEL,OU=EU,DC=domain,DC=net" -Filter * -Properties * | Select whenCreated, @{Name="Lastlogon"; Expression={[DateTime]::FromFileTime($_.lastLogonTimestamp)}}, Name,displayName, sn,  givenName, sAMAccountName, title, description, employeeType, info, department, company, homeDirectory, scriptPath, physicalDeliveryOfficeName, @{Label="Managed By"; expression= { Manager $_ } } | Export-Csv $OutputPath"BEL Service Accounts.csv" -NoTypeInformation -Delimiter ";" -Encoding utf8; start $OutputPath"BEL Service Accounts.csv"}
      4{# Users with an incorrect display name or city
        Get-ADUser -SearchBase "OU=BEL,OU=EU,DC=domain,DC=net" -Filter * -Properties * | where {$_.cn -NotLike "*$($_.l)*" -and $_.distinguishedname -notmatch 'OU=Terminated Users,OU=BEL,OU=EU,DC=grouphc,DC=net' -and $_.cn -ne "BNL Service Desk"} | Select whenCreated, Name,displayName, sn,  givenName, sAMAccountName, title, description, employeeType, info, department, company, homeDirectory, scriptPath, physicalDeliveryOfficeName, @{Label="Managed By"; expression= { Manager $_ } } | Export-Csv $OutputPath"Incorrect users.csv" -NoTypeInformation -Delimiter ";" -Encoding utf8; start $OutputPath"Incorrect users.csv"}
      5{# Users de-provisioned within 3 weeks
        $LogonDate = ((Get-Date).AddDays(-80)).Date # GIT 104 days KB-3872
        $CreaDate = ((Get-Date).AddDays(-60)).Date # GIT 60 days
        $PwdDate = ((Get-Date).AddDays(-90)).Date # GIT 90 days
        Get-ADUser -SearchBase "OU=Users,OU=BEL,OU=EU,DC=grouphc,DC=net" -Filter {(lastLogonDate -le $LogonDate) -and (WhenCreated -lt $CreaDate) -and (PwdLastSet -le $PwdDate)} -Properties * | Select LastLogonDate, WhenCreated, PasswordLastSet, Name,  title, description, employeeType, info, department, company, homeDirectory, scriptPath, physicalDeliveryOfficeName, @{Label="Managed By"; expression= { Manager $_ } } | Export-Csv $OutputPath"To be deprovisioned.csv" -NoTypeInformation -Delimiter ";" -Encoding utf8; start $OutputPath"To be deprovisioned.csv"}
      6{# Files/Folders: Activate inheritance & set owner to admin
        Get-ADUser -SearchBase "OU=BEL,OU=EU,DC=domain,DC=net" -Filter * -Properties * | where {$_.cn -NotLike "*$($_.l)*" -and $_.distinguishedname -notmatch 'OU=Terminated Users,OU=BEL,OU=EU,DC=grouphc,DC=net' -and $_.cn -ne "BNL Service Desk"} | Select whenCreated, Name,displayName, sn,  givenName, sAMAccountName, title, description, employeeType, info, department, company, homeDirectory, scriptPath, physicalDeliveryOfficeName, @{Label="Managed By"; expression= { Manager $_ } } | Export-Csv $OutputPath"Incorrect users.csv" -NoTypeInformation -Delimiter ";" -Encoding utf8; start $OutputPath"Incorrect users.csv"}
    }
  }
} while ( $userMenuChoice -ne 7 )
cls
 Write-Host "We left here because there's nothing else to do.."

权限脚本:

####### TO DO #######
$Target = "\\domain.net\SHARE\Target"


# Change FOLDER owners to Admin
If (Test-Path C:\PTemp) { Remove-Item C:\PTemp }
New-Item -type directory -Path C:\PTemp > $null

Write-Output "`nStart setting folder permissions on:"

$Folders = @(Get-ChildItem -Path $Target -Directory -Recurse | Select-Object -ExpandProperty FullName)
foreach ($Item1 in $Folders) 
{
# Action
Write-Output $Item1
$AdjustTokenPrivileges = @"
using System;
using System.Runtime.InteropServices;

 public class TokenManipulator
 {
  [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
  internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
  ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
  [DllImport("kernel32.dll", ExactSpelling = true)]
  internal static extern IntPtr GetCurrentProcess();
  [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
  internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr
  phtok);
  [DllImport("advapi32.dll", SetLastError = true)]
  internal static extern bool LookupPrivilegeValue(string host, string name,
  ref long pluid);
  [StructLayout(LayoutKind.Sequential, Pack = 1)]
  internal struct TokPriv1Luid
  {
   public int Count;
   public long Luid;
   public int Attr;
  }
  internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
  internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
  internal const int TOKEN_QUERY = 0x00000008;
  internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
  public static bool AddPrivilege(string privilege)
  {
   try
   {
    bool retVal;
    TokPriv1Luid tp;
    IntPtr hproc = GetCurrentProcess();
    IntPtr htok = IntPtr.Zero;
    retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
    tp.Count = 1;
    tp.Luid = 0;
    tp.Attr = SE_PRIVILEGE_ENABLED;
    retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
    retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
    return retVal;
   }
   catch (Exception ex)
   {
    throw ex;
   }
  }
  public static bool RemovePrivilege(string privilege)
  {
   try
   {
    bool retVal;
    TokPriv1Luid tp;
    IntPtr hproc = GetCurrentProcess();
    IntPtr htok = IntPtr.Zero;
    retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
    tp.Count = 1;
    tp.Luid = 0;
    tp.Attr = SE_PRIVILEGE_DISABLED;
    retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
    retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
    return retVal;
   }
   catch (Exception ex)
   {
    throw ex;
   }
  }
 }
"@
add-type $AdjustTokenPrivileges
$Folder = Get-Item $Item1
[void][TokenManipulator]::AddPrivilege("SeRestorePrivilege") 
[void][TokenManipulator]::AddPrivilege("SeBackupPrivilege") 
[void][TokenManipulator]::AddPrivilege("SeTakeOwnershipPrivilege") 
$NewOwnerACL = New-Object System.Security.AccessControl.DirectorySecurity
$Admin = New-Object System.Security.Principal.NTAccount("BUILTIN\Administrators")
$NewOwnerACL.SetOwner($Admin)
$Folder.SetAccessControl($NewOwnerACL)
# Add folder Admins to ACL with Full Control to descend folder structure
$Acl = Get-Acl -Path C:\PTemp
$Ar = New-Object  system.security.accesscontrol.filesystemaccessrule("BUILTIN\Administrators","FullControl","Allow")
$Acl.SetAccessRule($Ar)
Set-Acl $Item1 $Acl
} 

# Change FILE owners to Admin
If (Test-Path C:\PFile) { Remove-Item C:\PFile }
New-Item -type file -Path C:\PFile  > $null

Write-Output "`nStart setting file permissions on:"

$Files = @(Get-ChildItem -Path $Target -File -Recurse | Select-Object -ExpandProperty FullName)
foreach ($Item2 in $Files)
{
# Action
Write-Output $Item2
$Account = New-Object System.Security.Principal.NTAccount("BUILTIN\Administrators")
$FileSecurity = new-object System.Security.AccessControl.FileSecurity
$FileSecurity.SetOwner($Account)
[System.IO.File]::SetAccessControl($Item2, $FileSecurity)
# Add file Admins to ACL with Full Control and activate inheritance
$PAcl = Get-Acl -Path C:\PFile
$PAr = New-Object  system.security.accesscontrol.filesystemaccessrule("BUILTIN\Administrators","FullControl","Allow")
$PAcl.SetAccessRule($PAr)
Set-Acl $Item2 $PAcl
}

# Clean-up junk
Write-Output "`nCleaning up.."
rm C:\PTemp, C:\PFile
Write-Output "`nAll done :)"

到目前为止,我尝试过的代码块更短,但也没有成功:

6{# Test
Start-Process powershell {Get-ADUser -SearchBase "OU=Users,OU=BEL,OU=EU,DC=domain,DC=net" -Filter * -Properties * | Select whenCreated, @{Name="Lastlogon"; Expression={[DateTime]::FromFileTime($_.lastLogonTimestamp)}}, Name,displayName, sn,  givenName, sAMAccountName, title, description, employeeType, info, department, company, homeDirectory, scriptPath, physicalDeliveryOfficeName, @{Label="Managed By"; expression= { Manager $_ } } | Export-Csv $OutputPath"BEL Service Accounts.csv" -NoTypeInformation -Delimiter ";" -Encoding utf8; start $OutputPath"BEL Service Accounts.csv"}}}

【问题讨论】:

    标签: powershell


    【解决方案1】:

    您可以:

    start powershell {echo hello}
    

    为了防止新启动的 powershell 立即退出:

    start powershell {echo hello; Read-Host}
    

    【讨论】:

    • 我发现start powershell 只能处理某些命令,而不能处理其他命令。 invoke-expression 似乎更笼统。例如,请参阅我的答案。
    • 注意startstart-process的别名
    • 要在新窗口中使用参数启动另一个脚本,请使用start powershell {C:\script.ps1 -arg1 value -arg2 value}
    【解决方案2】:

    要在外部 PS 窗口中启动,您可以使用以下命令:

    invoke-expression 'cmd /c start powershell -Command { [script block here] }'
    

    例如:

    invoke-expression 'cmd /c start powershell -Command { write-host "Hi, new window!"; set-location "C:\"; get-childitem ; sleep 3}'
    

    【讨论】:

    • 谢谢 Arco444,您的示例运行良好。但由于某种原因,它不适用于我的代码块。难道是因为里面有.Net代码?
    • 错误是什么?确保用; 分隔命令,转义所有引号和特殊字符等。让命令调用单独的脚本肯定比尝试内联传递它更容易,所以我会认真考虑这种方法。跨度>
    • 嗨@arco444 你是对的,调用脚本可能更容易。现在让我们用谷歌搜索那个命令,这样我就可以使用它了。感谢您的提示!
    【解决方案3】:

    使用cmd启动powershell?

    start-process powershell -ArgumentList '-noexit -command 'Commands for the new PowerShell''
    

    【讨论】:

    • 你应该在单引号内使用双引号;否则,你会提前断线
    【解决方案4】:

    虽然start powershell 命令看起来更简洁,但它并不能让你做你可以用invoke-expression 做的所有事情。例如,以下打开一个新窗口,更改其标题和背景颜色,并使窗口保持打开状态:

    invoke-expression 'cmd /c start powershell -NoExit -Command {                           `
        cd -path $env:homedrive$env:homepath/Documents/MySillyFolder;                  `
        $host.UI.RawUI.WindowTitle = "A Silly Little Title";                                `
        color -background "red";                                                            `
    }';
    

    它也可以在另一个 powershell 脚本中正常运行。

    如果您尝试使用start powershell {...} 语法来执行此操作,它将在标题更改行出现错误,并且不会保持窗口打开。 (我想可能有一些晦涩的语法技巧可以使start powershell 工作,但我一直找不到。)

    【讨论】:

    • start powershell { $host.UI.RawUI.WindowTitle='xxxx' ; Read-Host } 对我来说似乎工作正常(并且尊重我配置的终端应用程序)。我怀疑您在标题更改行中使用了双引号 (") 而不是单引号 (')。
    猜你喜欢
    • 2015-03-22
    • 2013-02-16
    • 1970-01-01
    • 2018-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-23
    相关资源
    最近更新 更多