قائمة البرامج المثبتة باستخدام 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
		يسترجع قائمة بجميع البرامج المثبتة على جهاز كمبيوتر بنظام التشغيل ويندوز.
	.EXAMPLE
		PS> Get-InstalledSoftware
		
		يسترجع هذا المثال جميع البرامج المثبتة على الكمبيوتر المحلي.
	.PARAMETER ComputerName
		إذا كنت تستعلم عن جهاز كمبيوتر عن بُعد، استخدم اسم الكمبيوتر هنا.
	
	.PARAMETER Name
		عنوان البرنامج الذي ترغب في تحديد الاستعلام عنه.
	
	.PARAMETER 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/