Powershell новичок - PullRequest
       66

Powershell новичок

0 голосов
/ 18 февраля 2020

Я новичок в powershell, поэтому, пожалуйста, прости меня, если мой вопрос звучит глупо. Я нашел скрипт ниже от Юрия Посиделова, который я настроил, чтобы активировать процесс, показать окно и отправить нажатия клавиш, чтобы завершить процесс, который прекрасно работает. Однако, если два процесса с одинаковыми именами могут мне помочь, это может сработать.

Оригинальный код Юрия Посиделова

param([string] $proc="SBDDesktop", [string]$adm)

cls


Add-Type @"

  using System;

  using System.Runtime.InteropServices;

  public class WinAp {

     [DllImport("user32.dll")]

     [return: MarshalAs(UnmanagedType.Bool)]

     public static extern bool SetForegroundWindow(IntPtr hWnd);


     [DllImport("user32.dll")]

     [return: MarshalAs(UnmanagedType.Bool)]

     public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

  }


"@

$p = Get-Process |where {$_.mainWindowTItle }|where {$_.Name -like "$proc"}


if (($p -eq $null) -and ($adm -ne ""))

{

    Start-Process "$proc" -Verb runAs

}

elseif (($p -eq $null) -and ($adm -eq ""))

{

    Start-Process "$proc" #-Verb runAs

}

else

{

    $h = $p.MainWindowHandle


    [void] [WinAp]::SetForegroundWindow($h)

    [void] [WinAp]::ShowWindow($h,3);


    $wshell = New-Object -ComObject wscript.shell;

    #$wshell.SendKeys('~')

    $wshell.SendKeys('%fx')

    sleep 1

    $wshell.SendKeys('N')


}


#|format-table id,name,mainwindowtitle –AutoSize

# static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

# powershell.exe -windowstyle hidden -file *.ps1 -adm "a"

Ответы [ 3 ]

1 голос
/ 18 февраля 2020

Проблема в том, что строка $p = Get-Process |where {$_.mainWindowTItle }|where {$_.Name -like "$proc"} создаст объект типа array, если в нем более одного процесса. В противном случае он создаст объект типа System.ComponentModel.Component. Вы можете проверить это с помощью:

$p.GetType()

Чтобы компенсировать это, вы можете выполнить код foreach процесс в массиве, даже если в этом массиве только один элемент:

...
[array]$array = Get-Process |where {$_.mainWindowTItle }|where {$_.Name -like "$proc"}

foreach ($p in $array){


    if (($p -eq $null) -and ($adm -ne ""))

    {

        Start-Process "$proc" -Verb runAs

    }

    elseif (($p -eq $null) -and ($adm -eq ""))

    {

        Start-Process "$proc" #-Verb runAs

    }

    else

    {

        $h = $p.MainWindowHandle


        [void] [WinAp]::SetForegroundWindow($h)

        [void] [WinAp]::ShowWindow($h,3);


        $wshell = New-Object -ComObject wscript.shell;

        #$wshell.SendKeys('~')

        $wshell.SendKeys('%fx')

        sleep 1

        $wshell.SendKeys('N')


    }


    #|format-table id,name,mainwindowtitle –AutoSize

    # static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    # powershell.exe -windowstyle hidden -file *.ps1 -adm "a"

}
0 голосов
/ 18 февраля 2020

Get-Process вернет все процессы, которые соответствуют вашим критериям, что означает, что он вернет несколько объектов в переменную $p.

Так что вам нужно перебрать их, вы можете просто использовать foreach л oop

foreach($process in $p){
    if (($process -eq $null) -and ($adm -ne ""))

    {

        Start-Process "$proc" -Verb runAs

    }

    elseif (($$process -eq $null) -and ($adm -eq ""))

    {

        Start-Process "$proc" #-Verb runAs

    }

    else

    {

        $h = $process.MainWindowHandle


        [void] [WinAp]::SetForegroundWindow($h)

        [void] [WinAp]::ShowWindow($h,3);


        $wshell = New-Object -ComObject wscript.shell;

        #$wshell.SendKeys('~')

        $wshell.SendKeys('%fx')

        sleep 1

        $wshell.SendKeys('N')


    }
}
0 голосов
/ 18 февраля 2020

Если более одной дескриптора окна, сделайте все oop:

$processList = [object[]]@( Get-Process |where {$_.mainWindowTItle }|where {$_.Name -like "$proc"} )

foreach( $p in $processList ) {

    if (($p -eq $null) -and ($adm -ne "")) {
        Start-Process "$proc" -Verb runAs
    }
    elseif (($p -eq $null) -and ($adm -eq "")) {
        Start-Process "$proc" #-Verb runAs
    }
    else {

        $h = $p.MainWindowHandle

        [WinAp]::SetForegroundWindow($h) | Out-Null

        [WinAp]::ShowWindow($h,3) | Out-Null


        $wshell = New-Object -ComObject wscript.shell;

        #[void]$wshell.SendKeys('~')

        [void]$wshell.SendKeys('%fx')

        sleep 1 | Out-Null

        [void]$wshell.SendKeys('N')
    }
}
...