רשימת תוכנות מותקנות עם PowerShell: כלי חינמי

אם אתה מנהל מערכת, אחד מהעבודות שלך הוא להתקין, לשדרג ולהסיר תוכנות ממספר רב של מערכות. מה אם אני אגיד לך שאין צורך להתחבר לכל מכונה ולבדוק ידנית אם תוכנה מותקנת? באמת ניתן לרשום תוכנות המותקנות באמצעות PowerShell!

בפוסט הבלוג הזה, אני אראה לך איך לרשום תוכנות המותקנות באמצעות PowerShell על המכונה המקומית שלך ועל המכונות הרבות בו זמנית.

Listing installed software with PowerShell script

שים לב שמאמרים רבים עשויים להציע לך לעשות משהו כמו Get-WmiObject -Class win32_product. אל תעשה את זה. למד למה כאן.

תוכנות המותקנות והרגיסטר

למטרת הפניה, תוכנות המותקנות קיימות בשלושה מקומות:

  • מפתח ההסרה של מערכת ההתקנה של 32 ביט
  • מפתח ההסרה של מערכת ההתקנה של 64 ביט
  • מפתח ההסרה של כל פרופיל משתמש.

כל רשומת תוכנה מוגדרת בדרך כלל על ידי המזהה הגלובלי ייחודי של התוכנה (GUID). פנימה למפתח ה-GUID מכילה את כל המידע על תוכנה זו. כדי לקבל רשימה מלאה, PowerShell חייבת לספור את כל המפתחות האלה, לקרוא כל ערך ברגיסטר ולנתח את התוצאות.

מאחר שהקוד לניתוח נכון של ערכים אלו הוא הרבה יותר ממה שמאמר אחד יכול להכיל, יש לי פונקציה מובנית בשם Get-InstalledSoftware לרשימת תוכנות שהותקנו עם PowerShell שמסתירה את כל הקוד הזה בשבילך כפי שאתה רואה מטה שמפרטת תוכנות מותקנות במחשב.

function Get-InstalledSoftware {
    <#
	.SYNOPSIS
		משיג רשימה של כל התוכנות המותקנות במחשב Windows.
	.EXAMPLE
		PS> Get-InstalledSoftware
		
		דוגמה זו משיגה את כל התוכנות המותקנות במחשב המקומי.
	.PARAMETER ComputerName
		אם אתה משיג מידע ממחשב מרוחק, יש להשתמש בשם המחשב כאן.
	
	.PARAMETER Name
		כותרת התוכנה שתרצה להגביל את השאילתה אליה.
	
	.PARAMETER Guid
		ה-GUID של התוכנה שתרצה להגביל את השאילתה אליה.
	#>
    [CmdletBinding()]
    param (
		
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [string]$ComputerName = $env:COMPUTERNAME,
		
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [string]$Name,
		
        [Parameter()]
        [guid]$Guid
    )
    process {
        try {
            $scriptBlock = {
                $args[0].GetEnumerator() | ForEach-Object { New-Variable -Name $_.Key -Value $_.Value }
				
                $UninstallKeys = @(
                    "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall",
                    "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
                )
                New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS | Out-Null
                $UninstallKeys += Get-ChildItem HKU: | where { $_.Name -match 'S-\d-\d+-(\d+-){1,14}\d+$' } | foreach {
                    "HKU:\$($_.PSChildName)\Software\Microsoft\Windows\CurrentVersion\Uninstall"
                }
                if (-not $UninstallKeys) {
                    Write-Warning -Message 'No software registry keys found'
                } else {
                    foreach ($UninstallKey in $UninstallKeys) {
                        $friendlyNames = @{
                            'DisplayName'    = 'Name'
                            'DisplayVersion' = 'Version'
                        }
                        Write-Verbose -Message "Checking uninstall key [$($UninstallKey)]"
                        if ($Name) {
                            $WhereBlock = { $_.GetValue('DisplayName') -like "$Name*" }
                        } elseif ($GUID) {
                            $WhereBlock = { $_.PsChildName -eq $Guid.Guid }
                        } else {
                            $WhereBlock = { $_.GetValue('DisplayName') }
                        }
                        $SwKeys = Get-ChildItem -Path $UninstallKey -ErrorAction SilentlyContinue | Where-Object $WhereBlock
                        if (-not $SwKeys) {
                            Write-Verbose -Message "No software keys in uninstall key $UninstallKey"
                        } else {
                            foreach ($SwKey in $SwKeys) {
                                $output = @{ }
                                foreach ($ValName in $SwKey.GetValueNames()) {
                                    if ($ValName -ne 'Version') {
                                        $output.InstallLocation = ''
                                        if ($ValName -eq 'InstallLocation' -and 
                                            ($SwKey.GetValue($ValName)) -and 
                                            (@('C:', 'C:\Windows', 'C:\Windows\System32', 'C:\Windows\SysWOW64') -notcontains $SwKey.GetValue($ValName).TrimEnd('\'))) {
                                            $output.InstallLocation = $SwKey.GetValue($ValName).TrimEnd('\')
                                        }
                                        [string]$ValData = $SwKey.GetValue($ValName)
                                        if ($friendlyNames[$ValName]) {
                                            $output[$friendlyNames[$ValName]] = $ValData.Trim() ## חלק מערכי הרישום כוללים רווחים מאחוריים סופיים.
                                        } else {
                                            $output[$ValName] = $ValData.Trim() ## חלק מערכי הרישום כוללים רווחים מאחוריים סופיים.
                                        }
                                    }
                                }
                                $output.GUID = ''
                                if ($SwKey.PSChildName -match '\b[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}\b') {
                                    $output.GUID = $SwKey.PSChildName
                                }
                                New-Object -TypeName PSObject -Prop $output
                            }
                        }
                    }
                }
            }
			
            if ($ComputerName -eq $env:COMPUTERNAME) {
                & $scriptBlock $PSBoundParameters
            } else {
                Invoke-Command -ComputerName $ComputerName -ScriptBlock $scriptBlock -ArgumentList $PSBoundParameters
            }
        } catch {
            Write-Error -Message "Error: $($_.Exception.Message) - Line Number: $($_.InvocationInfo.ScriptLineNumber)"
        }
    }
}

פעם שתעתיק ותדביק את הפונקציה הזו לקונסולת PowerShell שלך או תוסיף אותה לסקריפט שלך, תוכל לקרוא אותה באמצעות שימוש בשם המחשב המסוים עם פרמטר ה־ComputerName.

רשימת תוכנות מותקנות באמצעות PowerShell

PS> Get-InstalledSoftware -ComputerName XXXXX

כאשר אתה עושה זאת, תקבל אובייקט עבור כל תוכנה שהותקנה. אתה יכול לקבל מגוון רחב של מידע על התוכנה המותקנת כלשהי.

אם אתה יודע את שם התוכנה מראש, אתה יכול גם להשתמש בפרמטר Name כדי להגביל את החיפוש רק לתוכנה שתואמת את הערך הזה.

לדוגמה, אולי תרצה לבדוק אם Microsoft Visual C++ 2005 Redistributable (x64) מותקן. פשוט תשתמש בערך זה כערך לפרמטר Name כפי שמוצג למטה.

PS> Get-InstalledSoftware -ComputerName MYCOMPUTER -Name 'Microsoft VisualC++ 2005 Redistributable (x64)'

סיכום

על ידי שימוש ב-PowerShell לקבלת תוכנה מותקנת, תוכל לבנות כלי ללא תשלום לחלוטין שתוכלו אתה וצוותך להשתמש בו כדי למצוא בקלות תוכנות מותקנות על מספר רב של מחשבים במערכת הפעלה Windows!

Source:
https://adamtheautomator.com/powershell-list-installed-software/