02 June 2016

PowerShell: Uninstall Windows 10 Built-In Applications with Verification

I am in the beginning stages of building a Windows 10 image for the firm I work at. One of the things that needs to be configured is the built-in apps. Obviously, we do not want all of them. You maybe wondering why you would use this over GPO or DSC. Those are fine for a blanket setting for all machines, but some apps maybe removed, but then allowed to be reinstalled on demand, which this script would be needed for.

With the help of Sapien's PowerShell Studio in building this script, I decided to make it multi-functional. It can generate a list of all built-in apps and display the formatted names to a screen. It can also output the list to a text file with the actual names of the apps needed to uninstall them. The script can uninstall a single app via command line parameters. It can also uninstall multiple app via a text file containing the application names. You can also hard code the specific uninstalls at the bottom of the script. Here are the five examples:


  • Generate a formatted list of all installed built-in apps
    • powershell.exe -executionpolicy bypass -command "UninstallBuilt-InApps.ps1 -GetAppList $true
  • Generate a list of all installed built-in apps and write the output to a log file
    • powershell.exe -executionpolicy bypass -command "UninstallBuilt-InApps.ps1 -GetAppList $true -Log $true
  • Uninstall a single built-in app by specifying its name at the command prompt. You do need to use the official name. You can get that by generating a formatted list.
    • powershell.exe -executionpolicy bypass -command "UninstallBuilt-InApps.ps1" -AppName "Microsoft.WindowsCamera"
  • Uninstall multiple built-in apps from a list inside a text file
    • powershell.exe -executionpolicy bypass -command "UninstallBuilt-InApps.ps1" -AppsFile "AppsUninstall.txt
  • Harcode the uninstall at the bottom of this script
    • Uninstall-BuiltInApp -AppName "Microsoft.WindowsCamera"

I included in the script the ability for it to verify the application was actually installed. While running, it will give an output to the screen with the status of each app it is uninstalling. I have only executed this on Windows 10, so I am not sure if it will work on Windows 8 and Windows 8.1, as we skipped those operating systems.

You can download the script from here.


1:  <#  
2:       .SYNOPSIS  
3:            Uninstall Build-In Apps  
4:         
5:       .DESCRIPTION  
6:            This script will uninstall built-in apps in Windows 10. The script can uninstall a single app by defining it at the command line. A list of apps can be read in from a text file and iterated through for uninstallation. Finally, they can also be hardcoded into the script.  
7:         
8:       .PARAMETER AppsFile  
9:            Text file to be read in by the script which contains a list of apps to uninstall.  
10:         
11:       .PARAMETER AppName  
12:            Name of the app to uninstall. This is defined when there is only one app to uninstall.  
13:         
14:       .PARAMETER GetAppList  
15:            True or false on generating a list of Built-in apps  
16:         
17:       .PARAMETER Log  
18:            Specify true or false on whether to generate a log file in the same directory as the script containing a list of all the built-in apps by their official name  
19:         
20:       .EXAMPLE  
21:            Generate a formatted list of all installed built-in apps  
22:                 powershell.exe -executionpolicy bypass -command "UninstallBuilt-InApps.ps1 -GetAppList $true  
23:    
24:            Generate a list of all installed built-in apps and write the output to a log file  
25:                 powershell.exe -executionpolicy bypass -command "UninstallBuilt-InApps.ps1 -GetAppList $true -Log $true  
26:    
27:            Uninstall a single built-in app by specifying its name at the command prompt. You do need to use the official name. You can get that by generating a formatted list.  
28:                 powershell.exe -executionpolicy bypass -command "UninstallBuilt-InApps.ps1" -AppName "Microsoft.WindowsCamera"  
29:              
30:            Uninstall multiple built-in apps from a list inside a text file  
31:                 powershell.exe -executionpolicy bypass -command "UninstallBuilt-InApps.ps1" -AppsFile "AppsUninstall.txt  
32:    
33:            Harcode the uninstall at the bottom of this script  
34:                 Uninstall-BuiltInApp -AppName "Microsoft.WindowsCamera"  
35:    
36:       .NOTES  
37:            ===========================================================================  
38:            Created with:     SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.2.122  
39:            Created on:       6/1/2016 3:21 PM  
40:            Created by:       Mick Pletcher  
41:            Organization:  
42:            Filename:         UninstallBuilt-InApps.ps1  
43:            ===========================================================================  
44:  #>  
45:  [CmdletBinding()]  
46:  param  
47:  (  
48:       [string]  
49:       $AppsFile = $null,  
50:       [string]  
51:       $AppName = $null,  
52:       [ValidateNotNullOrEmpty()][boolean]  
53:       $GetAppList = $false,  
54:       [ValidateNotNullOrEmpty()][boolean]  
55:       $Log = $false  
56:  )  
57:  Import-Module Appx  
58:    
59:  function Get-AppName {  
60:  <#  
61:       .SYNOPSIS  
62:            Format App name  
63:         
64:       .DESCRIPTION  
65:            This will format a built-in app name for proper display  
66:         
67:       .PARAMETER Name  
68:            Name of the application  
69:         
70:       .EXAMPLE  
71:                      PS C:\> Get-AppName -Name 'Value1'  
72:         
73:       .NOTES  
74:            Additional information about the function.  
75:  #>  
76:         
77:       [CmdletBinding()]  
78:       param  
79:       (  
80:            [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]  
81:            $Name  
82:       )  
83:         
84:       $Temp = $Name.Split('.')  
85:       For ($j = 0; $j -lt $Temp.Count; $j++) {  
86:            $Numeric = [bool]($Temp[$j] -as [double])  
87:            If ($Temp[$j] -eq 'Net') {  
88:                 $Temp[$j] = "." + $Temp[$j]  
89:            }  
90:            If ($Numeric -eq $true) {  
91:                 If ($Temp[$j + 1] -ne $null) {  
92:                      $Temp[$j] = $Temp[$j] + '.'  
93:                 }  
94:                 $FormattedName = $FormattedName + $Temp[$j]  
95:            } else {  
96:                 $FormattedName = $FormattedName + $Temp[$j] + [char]32  
97:            }  
98:       }  
99:       Return $FormattedName  
100:  }  
101:    
102:    
103:  function Get-BuiltInAppsList {  
104:  <#  
105:       .SYNOPSIS  
106:            List all Built-In Apps  
107:         
108:       .DESCRIPTION  
109:            Query for a list of all Build-In Apps  
110:         
111:       .EXAMPLE  
112:            PS C:\> Get-BuiltInAppsList  
113:         
114:       .NOTES  
115:            Additional information about the function.  
116:  #>  
117:         
118:       [CmdletBinding()]  
119:       param ()  
120:         
121:       $Apps = Get-AppxPackage  
122:       $Apps = $Apps.Name  
123:       $Apps = $Apps | Sort-Object  
124:       If ($Log -eq $true) {  
125:            $RelativePath = Get-RelativePath  
126:            $Apps | Out-File -FilePath $RelativePath"AllAppslist.txt" -Encoding UTF8  
127:       }  
128:       For ($i = 0; $i -lt $Apps.count; $i++) {  
129:            $Temp = Get-AppName -Name $Apps[$i]  
130:            $Apps[$i] = $Temp  
131:       }  
132:       $Apps  
133:  }  
134:    
135:  function Get-RelativePath {  
136:  <#  
137:       .SYNOPSIS  
138:            Get the relative path of the PowerShell script  
139:         
140:       .DESCRIPTION  
141:            Returns the path location of the PowerShell script being executed  
142:         
143:       .EXAMPLE  
144:            PS C:\> Get-RelativePath  
145:         
146:       .NOTES  
147:            Additional information about the function.  
148:  #>  
149:         
150:       [CmdletBinding()][OutputType([string])]  
151:       param ()  
152:         
153:       $RelativePath = (split-path $SCRIPT:MyInvocation.MyCommand.Path -parent) + "\"  
154:       Return $RelativePath  
155:  }  
156:    
157:  function Uninstall-BuiltInApp {  
158:  <#  
159:       .SYNOPSIS  
160:            Uninstall Windows 10 Built In App  
161:         
162:       .DESCRIPTION  
163:            This will uninstall a built-in app by passing the name of the app in.  
164:         
165:       .PARAMETER AppName  
166:            Name of the App  
167:         
168:       .EXAMPLE  
169:            PS C:\> Uninstall-BuiltInApp -AppName 'Value1'  
170:         
171:       .NOTES  
172:            Additional information about the function.  
173:  #>  
174:         
175:       [CmdletBinding()]  
176:       param  
177:       (  
178:            [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]  
179:            $AppName  
180:       )  
181:         
182:       $App = Get-AppName -Name $AppName  
183:       Write-Host "Uninstalling"$App"....." -NoNewline  
184:       $Output = Get-AppxPackage $AppName  
185:       If ($Output -eq $null) {  
186:            Write-Host "Not Installed" -ForegroundColor Yellow  
187:       } else {  
188:            $Output = Get-AppxPackage $AppName | Remove-AppxPackage  
189:            $Output = Get-AppxPackage $AppName  
190:            If ($Output -eq $null) {  
191:                 Write-Host "Success" -ForegroundColor Yellow  
192:            } else {  
193:                 Write-Host "Failed" -ForegroundColor Red  
194:            }  
195:       }  
196:  }  
197:    
198:  function Uninstall-BuiltInApps {  
199:  <#  
200:       .SYNOPSIS  
201:            Uninstall Windows 10 Built In Apps  
202:         
203:       .DESCRIPTION  
204:            This will uninstall a list of built-in apps by reading the app names from a text file located in the same directory as this script.  
205:         
206:       .NOTES  
207:            Additional information about the function.  
208:  #>  
209:         
210:       [CmdletBinding()]  
211:       param ()  
212:         
213:       $RelativePath = Get-RelativePath  
214:       $AppsFile = $RelativePath + $AppsFile  
215:       $List = Get-Content -Path $AppsFile  
216:       foreach ($App in $List) {  
217:            Uninstall-BuiltInApp -AppName $App  
218:       }  
219:  }  
220:    
221:  cls  
222:  #Generate list of all Build-In apps  
223:  If ($GetAppList -eq $true) {  
224:       Get-BuiltInAppsList  
225:  }  
226:  #Uninstall a single app  
227:  If (($AppName -ne $null) -and ($AppName -ne "")) {  
228:       Uninstall-BuiltInApp -AppName $AppName  
229:  }  
230:  #Read list of apps to uninstall from text file and uninstall all on the list  
231:  If (($GetAppList -ne $null) -and ($GetAppList -ne "")) {  
232:       Uninstall-BuiltInApps  
233:  }  
234:    

4 comments:

  1. Hi,
    It doesn't work for all users, just for current user.

    ReplyDelete
  2. Hi there, I am a little lost I think. Running Windows 10 with PS 5.0 and I am copying your commands you have written in your directions but it either does nothing, prompts for more input or returns some expression errors. Is your environment different? It doesn't work in mine on a newly deployed machine.

    ReplyDelete
  3. Thanks for the script, Mick.

    I think line 231 should reference the AppsFile variable instead of GetAppList.
    231: If (($AppsFile -ne $null) -and ($AppsFile -ne "")) {

    Also, the $GetAppList and $Log parameters would make great [switch] types which default to $false and are set to $true when referenced on the command line.
    Thus
    [switch]$GetAppList,
    [switch]$Log

    So the usage is just -GetAppList without the need to specify $true.

    Thanks!

    ReplyDelete