0

I am in a super hurry to try and find a way to query all of our Windows 7 computers on the corporate domain, and determine the last time they used Microsoft Office. We are under audit, that needs to be finished tomorrow (yep), and I want to see if we can uninstall Office before paying for licenses we don't need.

I haven't used PowerShell in a while, and frankly this is what I've found since starting on this code last night - i.e. newb. Maybe, there's a much better or easier way? I tried searching last night for a pre-done script or program, but couldn't find anything that says when Office was last used.

I can get the latest 'LastUse' using the below code and function, but I need to know which computer name that number is associated with. Right now it just returns the latest number: 20170928

function Measure-Latest {
BEGIN { $latest = $null }
PROCESS {
        if (($_ -ne $null) -and (($latest -eq $null) -or ($_ -gt $latest))) {
            $latest = $_ 

        }
}
END { $latest }
} 

$Software = Get-WmiObject -Class win32_softwarefeature | Select Caption,LastUse
$ComputerName = $env:COMPUTERNAME

$(foreach ($item in $Software) 
{
$Name = $Item.Caption
$LastUsedString = $Item.Lastuse.Substring(0,8)
$LastUsed = [int]$LastUsedString



    if ($Name -like 'Microsoft Office*' -or $Name -like 'Microsoft Outlook')  
       { 

        $LastUsed
            }   }) | Measure-Latest 
Gemini
  • 109
  • 2
  • 15

2 Answers2

1

The output was really just $LastUsed | Measure-Latest

Changed that to

$LastUsed = $LastUsed | Measure-Latest
If ($LastUsed -eq "19800000"){
    $LastUsed = "Never"
}
"$ComputerName : $Name : $LastUsed"

Full script below will give you the last use of all Microsoft Office products individually

function Measure-Latest {
    BEGIN { 
        $latest = $null 
    }
    PROCESS {
        if (($_ -ne $null) -and (($latest -eq $null) -or ($_ -gt $latest))) {
            $latest = $_ 
        }
    }
    END {
        $latest
    }
} 

$Software = Get-WmiObject -Class win32_softwarefeature | Select Caption,LastUse
$ComputerName = $env:COMPUTERNAME
foreach ($item in $Software) {
    $Name = $Item.Caption
    $LastUsedString = $Item.Lastuse.Substring(0,8)
    $LastUsed = [int]$LastUsedString
    if ($Name -like 'Microsoft Office*' -or $Name -like 'Microsoft Outlook') { 
        $LastUsed = $LastUsed | Measure-Latest
        If ($LastUsed -eq "19800000"){
            $LastUsed = "Never"
        }
        "$ComputerName : $Name : $LastUsed"
    }   
}

If you would like just the last time any Office Product was used then store the output of the for each in a variable and call it with $Computername variable

function Measure-Latest {
    BEGIN { 
        $latest = $null 
    }
    PROCESS {
        if (($_ -ne $null) -and (($latest -eq $null) -or ($_ -gt $latest))) {
            $latest = $_ 
        }
    }
    END {
        $latest
    }
} 

$Software = Get-WmiObject -Class win32_softwarefeature | Select Caption,LastUse
$ComputerName = $env:COMPUTERNAME
$LastRun = $(foreach ($item in $Software) {
    $Name = $Item.Caption
    $LastUsedString = $Item.Lastuse.Substring(0,8)
    $LastUsed = [int]$LastUsedString
    if ($Name -like 'Microsoft Office*' -or $Name -like 'Microsoft Outlook') { 
        $LastUsed
    }   
}) | Measure-Latest

"$ComputerName : $LastRun"
ArcSet
  • 6,518
  • 1
  • 20
  • 34
  • Thanks a ton ArcSet, you and BenH really saved me! Unfortunately, we only had 5 computers that hadn't used Office in the last year, but at least we know! :) – Gemini Sep 29 '17 at 15:22
1

I think this might be what you are looking for if you are running it local on each machine:

Get-WmiObject -Class Win32_SoftwareFeature |
    Where-Object {$_.Caption -match 'Microsoft\sOffice|Microsoft\sOutlook'} |
    Select-Object Caption, @{n='LastUse';e={[int]($_.Lastuse.Substring(0, 8))}},@{n='ComputerName';e={$env:COMPUTERNAME}} |
    Sort-Object LastUse |
    Select-Object -Last 1

If you are running it against a list of remote computers

$ComputerNames = Get-Content C:\example\list.txt
Get-WmiObject -Class win32_softwarefeature -ComputerName $ComputerNames |
    Where-Object {$_.Caption -match 'Microsoft\sOffice|Microsoft\sOutlook'} |
    Select-Object Caption, @{n='LastUse';e={[int]($_.Lastuse.Substring(0, 8))}},PSComputername |
    Group-Object PSComputername |
    ForEach-Object {
        $Group = $_.Group |
            Sort-Object LastUse |
            Select-Object -Last 1
        [PSCustomObject]@{
            ComputerName = $_.Name
            Caption = $Group.Caption
            LastUse = $Group.LastUse
        }
    }
BenH
  • 9,766
  • 1
  • 22
  • 35
  • I keep getting this error when trying to run the above script against remote Windows 7 computers. I have tried adding admin credentials and -impersonation 3 with no luck. Any thoughts? Get-WmiObject : Generic failure – Gemini Sep 28 '17 at 21:44
  • Despite the constant Generic failure error every time it connects to a remote computer, this script does generate the correct output at the end. Thanks a lot BenH, you really saved me! – Gemini Sep 28 '17 at 23:01