Checking What Office version is installed on network PCs exporting-append to csv

This topic contains 2 replies, has 2 voices, and was last updated by Profile photo of SkadaSnafu SkadaSnafu 2 months ago.

  • Author
    Posts
  • #70951
    Profile photo of SkadaSnafu
    SkadaSnafu
    Participant

    I am attempting to see what Office version is installed on network pcs so we can update only those that need our recent version per procedures. I really don't want to walk up to 500+ pcs and check what Office is installed.
    I understand that PSRemoting must be enabled on those machines.
    I am trying to use Get-RemoteProgram.ps1
    I want to get a list of PCs from a file (which is working), I want to get all listed versions of office (which is also working in my tests), and exclude anything that has "Update" in the program name ("Update" or "Security Update" things like that).

    This code works, but gives me all the updates in my output which is not desired.

    Get-Content -Path .\PClist.txt | ForEach-Object -Begin {. .\Get-RemoteProgram.ps1} -Process {Get-RemoteProgram -ComputerName $_} | Where-Object {$_.ProgramName -like '*Office*'} | Select-Object -Property ComputerName, ProgramName  | Export-Csv -Append -Path .\InstalledPrograms.csv -NoTypeInformation

    This code fails with a parsing error where

    Where-Object {$_.ProgramName -like '*Office*' -notmatch '*Update*'} 

    is located.

    Get-Content -Path .\PClist.txt | ForEach-Object -Begin {. .\Get-RemoteProgram.ps1} -Process {Get-RemoteProgram -ComputerName $_} | Where-Object {$_.ProgramName -like '*Office*' -notmatch '*Update*'} | Select-Object -Property ComputerName, ProgramName  | Export-Csv -Path .\InstalledPrograms.csv -NoTypeInformation

    Here is the exact error
    ————-
    parsing "*Update*" – Quantifier {x,y} following nothing.
    At line:1 char:146
    + ... ere-Object {$_.ProgramName -like '*Office*' -notmatch '*Update*'} | S ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : OperationStopped: (:) [], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException
    —————
    I have also tried

    {$_.ProgramName -like "*Office*" -notmatch "*Update*"'} |

    and I have also tried

    {$_.ProgramName -like "*Office*" -notlike "*Update*"'} |

    Am I using the wrong selector(s) in the Where-Object?

    Here is the Get-RemoteProgram.ps1

    Function Get-RemoteProgram {
    
        [CmdletBinding(SupportsShouldProcess=$true)]
        param(
            [Parameter(ValueFromPipeline              =$true,
                       ValueFromPipelineByPropertyName=$true,
                       Position=0
            )]
            [string[]]
                $ComputerName = $env:COMPUTERNAME,
            [Parameter(Position=0)]
            [string[]]
                $Property,
            [switch]
                $ExcludeSimilar,
            [int]
                $SimilarWord
        )
    
        begin {
            $RegistryLocation = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\',
                                'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\'
            $HashProperty = @{}
            $SelectProperty = @('ProgramName','ComputerName')
            if ($Property) {
                $SelectProperty += $Property
            }
        }
    
        process {
            foreach ($Computer in $ComputerName) {
                $RegBase = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$Computer)
                $RegistryLocation | ForEach-Object {
                    $CurrentReg = $_
                    if ($RegBase) {
                        $CurrentRegKey = $RegBase.OpenSubKey($CurrentReg)
                        if ($CurrentRegKey) {
                            $CurrentRegKey.GetSubKeyNames() | ForEach-Object {
                                if ($Property) {
                                    foreach ($CurrentProperty in $Property) {
                                        $HashProperty.$CurrentProperty = ($RegBase.OpenSubKey("$CurrentReg$_")).GetValue($CurrentProperty)
                                    }
                                }
                                $HashProperty.ComputerName = $Computer
                                $HashProperty.ProgramName = ($DisplayName = ($RegBase.OpenSubKey("$CurrentReg$_")).GetValue('DisplayName'))
                                if ($DisplayName) {
                                    New-Object -TypeName PSCustomObject -Property $HashProperty |
                                    Select-Object -Property $SelectProperty
                                } 
                            }
                        }
                    }
                } | ForEach-Object -Begin {
                    if ($SimilarWord) {
                        $Regex = [regex]"(^(.+?\s){$SimilarWord}).*$|(.*)"
                    } else {
                        $Regex = [regex]"(^(.+?\s){3}).*$|(.*)"
                    }
                    [System.Collections.ArrayList]$Array = @()
                } -Process {
                    if ($ExcludeSimilar) {
                        $null = $Array.Add($_)
                    } else {
                        $_
                    }
                } -End {
                    if ($ExcludeSimilar) {
                        $Array | Select-Object -Property *,@{
                            name       = 'GroupedName'
                            expression = {
                                ($_.ProgramName -split $Regex)[1]
                            }
                        } |
                        Group-Object -Property 'GroupedName' | ForEach-Object {
                            $_.Group[0] | Select-Object -Property * -ExcludeProperty GroupedName
                        }
                    }
                }
            }
        }
    }
    
  • #70952
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    You need to specify the operator (and\or) and the object that -notlike is compared against, try:

    {($_.ProgramName -like "*Office*") -and ($_.ProgramName -notlike "*Update*"')}
    
  • #70985
    Profile photo of SkadaSnafu
    SkadaSnafu
    Participant

    That did indeed work. On your code there is an extra single '

    This code did work. Thanks. I should have seen it, next time I will be more observant.

    Get-Content -Path .\PClist.txt | ForEach-Object -Begin {. .\Get-RemoteProgram.ps1} -Process {Get-RemoteProgram -ComputerName $_} | Where-Object {($_.ProgramName -like "*Office*") -and ($_.ProgramName -notlike "*Update*")} | Select-Object -Property ComputerName, ProgramName  | Export-Csv -Append -Path .\InstalledPrograms.csv -NoTypeInformation

You must be logged in to reply to this topic.