11# Author: Blake Drumm ([email protected] )22# Date created: February 29th, 2024
3- # Date modified: March 20th , 2024
3+ # Date modified: March 23rd , 2024
44# Description: This script will allow you to make the System Center Operations Manager PowerShell module portable.
55# Run this on a server that is a SCOM Management Server or has the Console installed on it. The script will
66# zip up the output folder and all you have to do is copy the zip to a remote machine (where you want to install
@@ -142,14 +142,36 @@ Set-Content -Path "$folderPath\ConsoleFolderInfo.txt" -Value "$consoleFolder"
142142
143143Set-Content - Path " $folderPath \Install-SCOMModule.ps1" - Value @"
144144[CmdletBinding()]
145- param ()
146-
145+ param
146+ (
147+ [Parameter(Mandatory = `$ false)]
148+ [ValidateSet('Install', 'Uninstall')]
149+ `$ Action = 'Install'
150+ )
151+ function Time-Stamp
152+ {
153+ `$ todaysDate = (Get-Date)
154+ return "`$ (`$ todaysDate.ToLocalTime().ToShortDateString()) @ `$ (`$ todaysDate.ToLocalTime().ToLongTimeString()) - "
155+ }
147156if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
148157{
149- Write-Warning "This script must be run as an administrator!"
158+ Write-Warning "`$ (Time-Stamp) This script must be run as an administrator!"
150159 return
151160}
152161
162+ if (-NOT `$ PSScriptRoot)
163+ {
164+ `$ Path = `$ PWD.Path
165+ }
166+ else
167+ {
168+ `$ Path = `$ PSScriptRoot
169+ }
170+
171+ [System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
172+ `$ publish = New-Object System.EnterpriseServices.Internal.Publish
173+
174+ <#
153175# Define the registry path where .NET Framework versions are stored
154176`$ regPath = "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\"
155177
@@ -164,80 +186,125 @@ if (Test-Path `$regPath)
164186 # .NET Framework 4.8 release key: 528040
165187 if (`$ versionValue -ge 461808 -and `$ versionValue -lt 528040)
166188 {
167- Write-Output " - .NET Framework 4.7.2 is installed."
189+ Write-Output "`$ (Time-Stamp) - .NET Framework 4.7.2 is installed."
168190 }
169191 elseif (`$ versionValue -eq 528040)
170192 {
171- Write-Output " - .NET Framework 4.8 is installed."
193+ Write-Output "`$ (Time-Stamp) - .NET Framework 4.8 is installed."
172194 }
173195 elseif (`$ versionValue -gt 528040)
174196 {
175- Write-Output " - Higher than .NET Framework 4.8 is installed. Unable to proceed."
197+ Write-Output "`$ (Time-Stamp) - Higher than .NET Framework 4.8 is installed. Unable to proceed."
176198 return
177199 }
178200 else
179201 {
180- Write-Warning "Neither .NET Framework 4.7.2 nor 4.8 is installed. Unable to proceed."
202+ Write-Warning "`$ (Time-Stamp) Neither .NET Framework 4.7.2 nor 4.8 is installed. Unable to proceed."
181203 return
182204 }
183205}
184206else
185207{
186- Write-Warning "Unable to find .NET Framework 4.x installation. Unable to proceed."
208+ Write-Warning "`$ (Time-Stamp) Unable to find .NET Framework 4.x installation. Unable to proceed."
187209 return
188210}
211+ #>
189212
190-
191- `$ powerShellFolder = Get-Content .\PowerShellFolderInfo.txt
192- `$ serverFolder = Get-Content .\ServerFolderInfo.txt
193- `$ consoleFolder = Get-Content .\ConsoleFolderInfo.txt
213+ `$ powerShellFolder = Get-Content `$ Path\PowerShellFolderInfo.txt
214+ `$ serverFolder = Get-Content `$ Path\ServerFolderInfo.txt
215+ `$ consoleFolder = Get-Content `$ Path\ConsoleFolderInfo.txt
194216
195217try
196218{
197219 `$ gacPath = (Resolve-Path "C:\Windows\Microsoft.NET\assembly\GAC_MSIL" -ErrorAction Stop).Path
198220}
199221catch
200222{
201- Write-Warning "Unable to locate the path: 'C:\Windows\Microsoft.NET\assembly\GAC_MSIL'. Unable to proceed."
223+ Write-Warning "`$ (Time-Stamp) Unable to locate the path: 'C:\Windows\Microsoft.NET\assembly\GAC_MSIL'. Unable to proceed."
202224 return
203225}
204- Get-ChildItem ".\Microsoft.EnterpriseManagement*" | % {
205- `$ resolvePath = Resolve-Path `$ gacPath\`$ (`$ _.Name) -ErrorAction SilentlyContinue
206- if (-NOT `$ resolvePath)
226+ if (`$ Action -eq 'Install')
227+ {
228+ Get-ChildItem "`$ Path\Microsoft.EnterpriseManagement*" | % {
229+ `$ resolvePath = Resolve-Path `$ gacPath\`$ (`$ _.Name) -ErrorAction SilentlyContinue
230+ if (-NOT `$ resolvePath)
231+ {
232+ `$ publish.GacInstall("`$ (`$ _.FullName)")
233+ #Copy-Item -Path `$ _.FullName -Destination `$ gacPath -Force -Recurse
234+ }
235+ }
236+ New-Item -Path `$ powerShellFolder -ItemType Directory -Force | Out-Null
237+ Copy-Item -Path "`$ Path\Powershell\*" -Destination `$ powerShellFolder -Force -Recurse
238+
239+ New-Item -Path `$ serverFolder -ItemType Directory -Force | Out-Null
240+ Copy-Item -Path "`$ Path\Server\*" -Destination `$ serverFolder -Force -Recurse
241+
242+ New-Item -Path `$ consoleFolder -ItemType Directory -Force | Out-Null
243+ Copy-Item -Path "`$ Path\Console\*" -Destination `$ consoleFolder -Force -Recurse
244+
245+ # Get current PSModulePath and split into an array
246+ `$ envVariableArray = [Environment]::GetEnvironmentVariable("PSModulePath", "Machine") -split ';'
247+
248+ # Check if `$ powerShellFolder is already in the array
249+ if (`$ envVariableArray -notcontains `$ powerShellFolder)
207250 {
208- Copy-Item -Path `$ _.FullName -Destination `$ gacPath -Force -Recurse
251+ # If not, add it to the array
252+ `$ envVariableArray += `$ powerShellFolder
253+
254+ # Rejoin the array into a string with ";" and set the environment variable
255+ `$ newEnvVariable = `$ envVariableArray -join ';'
256+ [Environment]::SetEnvironmentVariable("PSModulePath", `$ newEnvVariable, "Machine")
257+
258+ Write-Output "`$ (Time-Stamp) - Added module to the machine level environmental variable (PSModulePath)"
259+ }
260+ else
261+ {
262+ Write-Output "`$ (Time-Stamp) - Module is already in the machine level environmental variable (PSModulePath)"
209263 }
210- }
211- Copy-Item -Path .\Powershell\ -Destination `$ powerShellFolder -Force -Recurse
212-
213- Copy-Item -Path .\Server\ -Destination `$ serverFolder -Force -Recurse
214-
215- Copy-Item -Path .\Console\ -Destination `$ consoleFolder -Force -Recurse
216-
217- `$ p = [Environment]::GetEnvironmentVariable("PSModulePath")
218- if (`$ p -notcontains `$ powerShellFolder)
219- {
220- `$ envVariable += "`$ p;`$ powerShellFolder"
221- [Environment]::SetEnvironmentVariable("PSModulePath", `$ envVariable, 'Machine')
222- Write-Output " - Added module to the machine level environmental variable (PSModulePath)"
223- }
224- else
225- {
226- Write-Output " - Module is already in the machine level environmental variable (PSModulePath)"
227- }
228264<#
229265try
230266{
231267 Import-Module OperationsManager -Verbose -ErrorAction Stop
232268}
233269catch
234270{
235- Write-Warning "Unable to import the SCOM PowerShell Module!`n`$ _"
271+ Write-Warning "`$ (Time-Stamp) Unable to import the SCOM PowerShell Module!`n`$ _"
236272 return
237273}
238- Write-Output "Completed importing the SCOM PowerShell Module!"
274+ Write-Output "`$ (Time-Stamp) Completed importing the SCOM PowerShell Module!"
239275#>
240- Write-Output "Close this window and reopen a new PowerShell window. Run the following command to import the Operations Manager PowerShell module: Import-Module OperationsManager"
276+ Write-Output "`$ (Time-Stamp)Close this window and reopen a new PowerShell window. Run the following command to import the Operations Manager PowerShell module: Import-Module OperationsManager"
277+ }
278+ elseif (`$ Action -eq 'Uninstall')
279+ {
280+ Get-ChildItem "`$ Path\Microsoft.EnterpriseManagement*" | % {
281+ `$ resolvedPath = (Resolve-Path `$ gacPath\`$ (`$ _.Name) -ErrorAction SilentlyContinue)
282+ if (`$ resolvedPath)
283+ {
284+ `$ publish.GacRemove("`$ resolvedPath")
285+ `$ publish.UnRegisterAssembly()
286+ }
287+ }
288+
289+ `$ resolvedPath = Resolve-Path `$ serverFolder -ErrorAction SilentlyContinue
290+ if (`$ resolvedPath)
291+ {
292+ Remove-Item -Path `$ resolvedPath -Force -Recurse
293+ }
294+
295+ `$ resolvedPath = Resolve-Path `$ consoleFolder -ErrorAction SilentlyContinue
296+ if (`$ resolvedPath)
297+ {
298+ Remove-Item -Path `$ resolvedPath -Force -Recurse
299+ }
300+
301+ `$ resolvedPath = Resolve-Path `$ powerShellFolder -ErrorAction SilentlyContinue
302+ if (`$ resolvedPath)
303+ {
304+ Remove-Item -Path `$ resolvedPath -Force -Recurse
305+ }
306+ Write-Output "`$ (Time-Stamp)Completed removing the SCOM PowerShell Module!"
307+ }
241308"@
242309
243310Set-Content - Path " $folderPath \Readme.txt" - Value @"
0 commit comments