Список в PowerShell - коллекция или многомерный массив? - PullRequest
0 голосов
/ 17 мая 2018

Я использую следующий код для создания списка и использую его для перезагрузки компьютера на основе отображаемого имени в списке.Я на самом деле хочу заменить отображаемое имя фактическим именем компьютера.Могу ли я использовать массив для этого?Я все еще привыкаю к ​​powershell.Если я не могу создать массив, есть ли в списке свойство или коллекция, в которой я могу сохранить имя компьютера?

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$form = New-Object System.Windows.Forms.Form
$form.Text = 'Select a Computer'
$form.Size = New-Object System.Drawing.Size(300,200)
$form.StartPosition = 'CenterScreen'

$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = 'OK'
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)

$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = 'Cancel'
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $CancelButton
$form.Controls.Add($CancelButton)

$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = 'Please select a computer:'
$form.Controls.Add($label)

$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10,40)
$listBox.Size = New-Object System.Drawing.Size(260,20)
$listBox.Height = 80

[void] $listBox.Items.Add('Screen in building 1 first floor')
[void] $listBox.Items.Add('Screen in building 1 second floor')
[void] $listBox.Items.Add('Screen in building 2 4th floor')
[void] $listBox.Items.Add('Screen in building 3 basement')

$form.Controls.Add($listBox)

$form.Topmost = $true

$result = $form.ShowDialog()

if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
    $c = Get-Credential Domain\Username
    Restart-Computer -ComputerName "Variable 2 of selection from listbox" -Credential $c -Force
    $x = $listBox.SelectedItem
    $x
}

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Это на самом деле довольно просто с объектами powershell.Создайте массив компьютерных объектов, которые определяют любые свойства (вы можете сделать это автоматически).Добавьте их в список и выберите элемент, который вы хотите отобразить.Позже вы также можете получить доступ к другому свойству (в данном случае SelectedItem.Name).

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$form = New-Object System.Windows.Forms.Form
$form.Text = 'Select a Computer'
$form.Size = New-Object System.Drawing.Size(300,200)
$form.StartPosition = 'CenterScreen'

$x = @()
$x += [pscustomobject]@{Name="cname"; Display="Friendly Name"}
$x += [pscustomobject]@{Name="cname2"; Display="Friendly Name2"}
$x += [pscustomobject]@{Name="cname3"; Display="Friendly Name3"}

$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10,40)
$listBox.Size = New-Object System.Drawing.Size(260,20)
$listBox.Height = 80
$listBox.Items.AddRange($x)
$listBox.DisplayMember = "Display"
$form.Controls.Add($listBox)

$labelDN = New-Object system.windows.Forms.Label
$labelDN.AutoSize = $true
$labelDN.Width = 25
$labelDN.Height = 10
$labelDN.location = new-object system.drawing.point(1,1)
$labelDN.Font = "Microsoft Sans Serif,10"
$labelDN.Text = "Hello"
$Form.controls.Add($labelDN)

$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = 'OK'
$OKButton.Add_Click({
 $labelDN.Text = $listBox.SelectedItem.Name
})
$form.Controls.Add($OKButton)


$form.ShowDialog()

Вы можете фактически добавить весь свой код в метод Add_Click, если хотите уменьшить его для себя.С вашим решением было немного сложно протестировать, поскольку оно закрывает приложение при каждом выборе.Конечно, вы можете реализовать это так, как хотите.

0 голосов
/ 17 мая 2018

Обновлено : в приведенном ниже примере я собираюсь использовать компьютеры из Active Directory, используя Import-Module ActiveDirectory

Чтобы добавить элементы к вашему listbox с помощью многомерного массива, мы можем использовать Object и NoteProperty для добавления к listbox

Ex:

#This example I am grabbing all computers from AD with the OS of windows server -- all windows servers
Import-Module ActiveDirectory
#Using the Name property for reboot and the Description for the listbox... you can use a different attribute if you like
$Computers = Get-ADComputer -filter {OperatingSystem -like "Windows Server*" -and Enabled -eq $true} -Properties Name, Description, OperatingSystem  | Select Name, Description, OperatingSystem

$listboxCollection =@()

foreach($Computer in $Computers)
{

    $Object = New-Object Object 
    $Object | Add-Member -type NoteProperty -Name CompName -Value $Computer.Name
    $Object | Add-Member -type NoteProperty -Name Values -Value $Computer.Description
    #fill the $listboxCollection
    $listboxCollection += $Object
}

#Add collection to the $listbox
$listBox.Items.AddRange($listboxCollection)

Если бы вы отображали здесь свою форму, все ваши записи показывались бы как System.Object. Чтобы получить Decription из каждой коллекции в $listboxCollection, чтобы показать, мы должны сказать ему ValueMember и DisplayMember.

Ex:

#This is using the properties above to display the correct item
$listBox.ValueMember = "CompName"
$listBox.DisplayMember = "Values"

Сохраняя исходное сообщение, чтобы получить выбранный элемент listbox на кнопке ОК, вам нужно будет поставить условие. Однако есть несколько различных способов обработки этого события.

Ex:

#show form as dialog
$result = $form.ShowDialog()

if($result = [System.Windows.Forms.DialogResult]::OK)
{
    $selectedComputer = $listBox.SelectedItem.CompName  
    Restart-Computer -ComputerName $selectedComputer -Credential Get-Credential Domain\Username -Force
}

Переменная $selectedComputer будет выбранным компьютером. Примечание. В этом примере ничего не проверяется, чтобы убедиться в правильности выбора.

Полное решение:

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing


#This example I am grabbing all computers from AD with the OS of windows server -- all windows servers
Import-Module ActiveDirectory
#Using the Name property for reboot and the Description for the listbox... you can use a different attribute if you like
$Computers = Get-ADComputer -filter {OperatingSystem -like "Windows Server*" -and Enabled -eq $true} -Properties Name, Description, OperatingSystem  | Select Name, Description, OperatingSystem

$form = New-Object System.Windows.Forms.Form
$form.Text = 'Select a Computer'
$form.Size = New-Object System.Drawing.Size(300,200)
$form.StartPosition = 'CenterScreen'

$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10,40)
$listBox.Size = New-Object System.Drawing.Size(260,20)
$listBox.Height = 80

#create an empty collection to use later
$listboxCollection =@()

foreach($Computer in $Computers)
{

    $Object = New-Object Object 
    $Object | Add-Member -type NoteProperty -Name CompName -Value $Computer.Name
    $Object | Add-Member -type NoteProperty -Name Values -Value $Computer.Description
    $listboxCollection += $Object
}

$listBox.Items.AddRange($listboxCollection)

#This is using the properties above to display the correct item
$listBox.ValueMember = "CompName"
$listBox.DisplayMember = "Values"


#add listbox to form
$form.Controls.Add($listBox)

#Ok Button
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = 'OK'
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)

#keep on top
$form.Topmost = $true

#show form as dialog
$result = $form.ShowDialog()

if($result = [System.Windows.Forms.DialogResult]::OK)
{
    #this tells it to get the Name of the property and not just the Item
    $selectedComputer = $listBox.SelectedItem.CompName    
    Restart-Computer -ComputerName $selectedComputer -Credential Get-Credential Domain\Username -Force
}

Примечание: если вы используете запрос Active Directory, все ваши компьютеры должны иметь атрибуты Name и Description (если, конечно, вы не планируете обрабатывать пустые / нулевые значения)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...