Сценарий Powershell - Как удалить несколько пакетов одновременно? - PullRequest
0 голосов
/ 14 апреля 2020

Я пытаюсь расширить свой существующий скрипт с помощью лучшего кода. Поэтому я хотел предоставить сценарию подтверждение, действительно ли программное обеспечение удалено или нет. Я пытался сделать это с foreach. Вот мой код:

function deletesoftware2 () {
$ErrorActionPreference = 'SilentlyContinue'
$appname = @(
    #"*HP Support Assistant*",
    #"*HP Support Solutions Framework*",
    #"*Dell SupportAssist*",
    #"*Dell Command | Update*",
    "*NuGet*"
)
ForEach($app in $appname){
    Write-Host "Removing $app from System"
    Get-Package -Name $app | Uninstall-Package -ErrorAction SilentlyContinue | Out-Null
        Start-Sleep -Seconds 20
    Get-Package | Where-Object{$_.Name -like $app} | Format-Table name | Out-String -OutVariable software | Out-Null
    if ($software -match $app) {
        Write-Host "$app wasnt found or could not removed"

    }
    else {
        Write-Host "$app was removed"   
    }        
}
Start-Sleep -Seconds 10

}

Редактировать: если я запускаю показанный скрипт, он сразу переходит в остальное, даже если программное обеспечение не удалено. Я попытался заменить «$ app» в if напрямую в NuGet, и это сработало. Но если я напишу host переменную $ app, она скажет именно Nuget, и это то, что я хочу. Дело в том, что это все равно не сработает.

Ну, это не сработает так, как я хочу, я был бы рад, если бы кто-нибудь смог мне помочь! Заранее спасибо!

1 Ответ

1 голос
/ 14 апреля 2020

Причина такого поведения в том, что Format-Table name | Out-String -OutVariable software даст несколько неожиданные результаты.

Давайте в качестве примера рассмотрим пакет Microsoft Teams, так как он доступен в моей системе.

$q = Get-Package | ? { $_.name -eq "Microsoft Teams" }
$q.Name
Microsoft Teams

$q.Name.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

Пока все выглядит хорошо. Теперь давайте добавим в игру Format-Table вот так:

$q | Format-Table name | Out-String -OutVariable software | Out-Null
$software

Name
----
Microsoft Teams

$software.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     ArrayList                                System.Object

Подождите, что? Тип совсем не такой. Это потому, что форматирование в виде таблицы создаст массив строк. Это никогда не будет соответствовать простому строковому имени пакета.

Что касается исправления, просто снова используйте Get-Package и присвойте его результат в переменной. Если такого пакета нет, результат будет равен $null. Вот так

Get-Package -Name $app | Uninstall-Package...
$q= Get-Package | Where-Object{$_.Name -like $app}
if($q -eq $null) {
    Write-Host "$app was removed"
}
else {
    Write-Host "$q is still present"
}
...