While working on the new Windows 10 build for my firm, it came up about updating the old script that generates a custom list of installed applications to a .CSV file on a weekly basis. The purpose of this report is so the build team has a concise list of optional applications they need to install during a replacement build for a user. Yes, they do have access to the SCCM Resource Manager, but the problem with that is combing through the list of a LOT of apps and trying to filter out which ones they need to install that are not included with the standard image. Our build team has really liked this script. This script filters all of the unnecessary apps out of the list. It will query a list of all installed apps from the add/remove programs entries within the registry. There is an external ExclusionList.txt file the script reads. This file contains a list of the applications you do not want to be included in the report. The application in the file need to be exactly how they appear in the report. You can copy and paste the apps from the report to the ExclusionList.txt file.
Thanks to Sapien's PowerShell Studio, I have been able to easily add some great new features to the script giving it the ability to rewrite the ExclusionList.txt file, thereby allowing it to be alphabetically sorted. It also removes copies of application names. To get around a bunch of systems writing to the same file at once, I used a Try | Catch encapsulated in a Do | While statement for writing to the file so errors will not pop up and if another system has already sorted and rewritten the ExclusionList.txt file, it will not occur again.
The script will write both to the screen and to the .CSV file. I added two parameters that allow you to define where the .CSV file is to be written and what filename you want it to be. Unlike the original script, this gives you the ease to write the logs to a network share instead of locally in the event a system failure occurs and you want the report for building a new system.
To use the script, I have it executed by an SCCM package once a week during prime business hours so that it runs on the maximum number of machines possible. The build team reports to me when new, unnecessary apps appear in the report so they can be added to the ExclusionList.txt file. If for some reason there is not a current report, such as a laptop has been offline for quite a long time, the script can be manually executed on a machine.
You can download the app from here.
InstalledApplications.ps1
Thanks to Sapien's PowerShell Studio, I have been able to easily add some great new features to the script giving it the ability to rewrite the ExclusionList.txt file, thereby allowing it to be alphabetically sorted. It also removes copies of application names. To get around a bunch of systems writing to the same file at once, I used a Try | Catch encapsulated in a Do | While statement for writing to the file so errors will not pop up and if another system has already sorted and rewritten the ExclusionList.txt file, it will not occur again.
The script will write both to the screen and to the .CSV file. I added two parameters that allow you to define where the .CSV file is to be written and what filename you want it to be. Unlike the original script, this gives you the ease to write the logs to a network share instead of locally in the event a system failure occurs and you want the report for building a new system.
To use the script, I have it executed by an SCCM package once a week during prime business hours so that it runs on the maximum number of machines possible. The build team reports to me when new, unnecessary apps appear in the report so they can be added to the ExclusionList.txt file. If for some reason there is not a current report, such as a laptop has been offline for quite a long time, the script can be manually executed on a machine.
You can download the app from here.
InstalledApplications.ps1
1: <#
2: .SYNOPSIS
3: Installed Applications
4:
5: .DESCRIPTION
6: This will retrieve the list of installed applications from add/remove programs and write the list to a .CSV file. The tool is executed on machines once a week via an SCCM Application deployment. It's purpose is to provide a custom report to a build team for when they need to rebuild systems without having to comb through the typical SCCM Add/Remove Programs report. The reports are customized by excluding applications that are written to the ExclusionList.txt file.
7:
8: .PARAMETER ReportFile
9: Name of the report file to be created. The report file should have the extension .CSV since this script writes to the file using UTF8 and in Excel format
10:
11: .PARAMETER ReportFileLocation
12: The directory where the report file is located
13:
14: .EXAMPLE
15: powershell.exe -executionpolicy bypass -file InstalledApplications.ps1
16:
17: .NOTES
18: ===========================================================================
19: Created with: SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.2.124
20: Created on: 7/8/2016 1:29 AM
21: Created by: Mick Pletcher
22: Organization:
23: Filename: InstalledApplications.ps1
24: ===========================================================================
25: #>
26: [CmdletBinding()]
27: param
28: (
29: [ValidateNotNullOrEmpty()][string]$ReportFile = 'Applications.csv',
30: [ValidateNotNullOrEmpty()][string]$ReportFileLocation = 'c:\windows\waller'
31: )
32:
33:
34: function Get-AddRemovePrograms {
35: <#
36: .SYNOPSIS
37: Retrieve a list of the Add/Remove Programs
38:
39: .DESCRIPTION
40: Retrieves the Add/Remove Programs list from the registry
41:
42: .NOTES
43: Additional information about the function.
44: #>
45:
46: [CmdletBinding()][OutputType([string])]
47: param ()
48:
49: $Architecture = Get-Architecture
50: if ($Architecture -eq "32-bit") {
51: $Applications = Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" | ForEach-Object -Process { $_.GetValue("DisplayName") }
52: } else {
53: $Applicationsx86 = Get-ChildItem -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\" | ForEach-Object -Process { $_.GetValue("DisplayName") }
54: $Applicationsx64 = Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" | ForEach-Object -Process { $_.GetValue("DisplayName") }
55: $Applications = $Applicationsx86 + $Applicationsx64
56: }
57: $Applications = $Applications | Sort-Object
58: $Applications = $Applications | Select-Object -Unique
59: Return $Applications
60: }
61:
62: function Get-Architecture {
63: <#
64: .SYNOPSIS
65: Get-Architecture
66:
67: .DESCRIPTION
68: Returns whether the system architecture is 32-bit or 64-bit
69:
70: .EXAMPLE
71: Get-Architecture
72:
73: .NOTES
74: Additional information about the function.
75: #>
76:
77: [CmdletBinding()][OutputType([string])]
78: param ()
79:
80: $OSArchitecture = Get-WmiObject -Class Win32_OperatingSystem | Select-Object OSArchitecture
81: $OSArchitecture = $OSArchitecture.OSArchitecture
82: Return $OSArchitecture
83: }
84:
85: function Get-RelativePath {
86: <#
87: .SYNOPSIS
88: Get the relative path
89:
90: .DESCRIPTION
91: Returns the location of the currently running PowerShell script
92:
93: .NOTES
94: Additional information about the function.
95: #>
96:
97: [CmdletBinding()][OutputType([string])]
98: param ()
99:
100: $Path = (split-path $SCRIPT:MyInvocation.MyCommand.Path -parent) + "\"
101: Return $Path
102: }
103:
104: function New-LogFile {
105: <#
106: .SYNOPSIS
107: Create a new log file
108:
109: .DESCRIPTION
110: Delete the old log file if it exists and/or create a new one
111:
112: .NOTES
113: Additional information about the function.
114: #>
115:
116: [CmdletBinding()]
117: param ()
118:
119: If ($ReportFileLocation[$ReportFileLocation.Count - 1] -eq '\') {
120: $File = $ReportFileLocation + $ReportFile
121: } else {
122: $File = $ReportFileLocation + '\' + $ReportFile
123: }
124: if ((Test-Path $File) -eq $true) {
125: Remove-Item -Path $File -Force | Out-Null
126: }
127: if ((Test-Path $File) -eq $false) {
128: New-Item -Path $File -ItemType file -Force | Out-Null
129: }
130: }
131:
132: function New-Report {
133: <#
134: .SYNOPSIS
135: Generate a new Add/Remove programs report
136:
137: .DESCRIPTION
138: This will generate the list of Add/Remove programs and write to the .CSV file.
139:
140: .PARAMETER Applications
141: List of Add/Remove programs applications
142:
143: .NOTES
144: Additional information about the function.
145: #>
146:
147: param
148: (
149: [ValidateNotNullOrEmpty()][object]$Applications
150: )
151:
152: If ($ReportFileLocation[$ReportFileLocation.Count - 1] -eq '\') {
153: $File = $ReportFileLocation + $ReportFile
154: } else {
155: $File = $ReportFileLocation + '\' + $ReportFile
156: }
157: If ((Test-Path $File) -eq $true) {
158: $Applications
159: Out-File -FilePath $File -InputObject $Applications -Append -Force -Encoding UTF8
160: } else {
161: Write-Host "Report File not present to generate report" -ForegroundColor Red
162: }
163: }
164:
165: function Update-AppList {
166: <#
167: .SYNOPSIS
168: Generate updated list of Apps
169:
170: .DESCRIPTION
171: Generate an updated list of apps by removing the apps listed in the exclusions.txt file. This function also sorts and rewrites the exclusion list back to the exclusion.txt file in the event new exclusions have been added.
172:
173: .PARAMETER Applications
174: List of Add/Remove programs applications
175:
176: .EXAMPLE
177: PS C:\> Update-AppList
178:
179: .NOTES
180: Additional information about the function.
181: #>
182:
183: [CmdletBinding()][OutputType([object])]
184: param
185: (
186: [ValidateNotNullOrEmpty()][object]$Applications
187: )
188:
189: $RelativePath = Get-RelativePath
190: $File = $RelativePath + "ExclusionList.txt"
191: If ((Test-Path $File) -eq $true) {
192: $Exclusions = Get-Content -Path $File
193: $SortedExclusions = $Exclusions | Sort-Object
194: $SortedExclusions = $SortedExclusions | Select-Object -Unique
195: $Sorted = !(Compare-Object $Exclusions $SortedExclusions -SyncWindow 0)
196: If ($Sorted -eq $false) {
197: Do {
198: Try {
199: $Exclusions = Get-Content -Path $File
200: $SortedExclusions = $Exclusions | Sort-Object
201: $SortedExclusions = $SortedExclusions | Select-Object -Unique
202: $Sorted = !(Compare-Object $Exclusions $SortedExclusions -SyncWindow 0)
203: If ($Sorted -eq $false) {
204: Out-File -FilePath $File -InputObject $SortedExclusions -Force -Encoding UTF8 -ErrorAction SilentlyContinue
205: }
206: $Success = $true
207: } Catch {
208: $Success = $false
209: }
210: }
211: while ($Success -eq $false)
212: }
213: $Applications = $Applications | Where-Object { ($_ -notin $SortedExclusions) -and ($_ -ne "") -and ($_ -ne $null) }
214: }
215: Return $Applications
216: }
217:
218: Clear-Host
219: New-LogFile
220: $Apps = Get-AddRemovePrograms
221: $Apps = Update-AppList -Applications $Apps
222: New-Report -Applications $Apps
223:
0 comments:
Post a Comment