ud-cmwt.psm1
<#
.SYNOPSIS Export AzureAD credentials to a JSON file .DESCRIPTION Import AzureAD credentials to a JSON file for use with CMWT .PARAMETER FilePath Path and filename. Default is "$($env:userprofile)\documents\cmwt-aad-cred.json" .PARAMETER Force Overwrite destination if it exists .EXAMPLE Export-CmwtCredential -Force .OUTPUTS JSON file .NOTES NOT the most secure way to store credentials! Protect access to this file! #> function Export-CmwtCredential { [CmdletBinding()] param ( [parameter()] [ValidateNotNullOrEmpty()] [string] $FilePath = $(Join-Path -Path $env:USERPROFILE -ChildPath "Documents\cmwt-aad-cred.json"), [parameter()] [switch] $Force ) if ((Test-Path $FilePath) -and (-not $Force)) { Write-Warning "File [$FilePath] exists! To overwrite, use the -Force parameter" break } else { $cred = Get-Credential -Message "AzureAD Credentials" if ($null -ne $cred) { $cred | Select-Object Username,@{n="Password"; e={$_.password | ConvertFrom-SecureString}} | ConvertTo-Json | Set-Content -Path $FilePath -Encoding UTF8 -Force } else { Write-Warning "Credentials were not provided for exporting." } } } <# .SYNOPSIS Import CMWT AzureAD credentials from JSON file .DESCRIPTION Import CMWT AzureAD credentials from JSON file created using Export-CmwtCredential .PARAMETER FilePath Path and filename. Default is "$($env:userprofile)\documents\cmwt-aad-cred.json" .EXAMPLE $aadCred = Import-CmwtCredential .OUTPUTS PSCredential object #> function Import-CmwtCredential { [CmdletBinding()] param ( [parameter()] [ValidateNotNullOrEmpty()] [string] $FilePath = $(Join-Path -Path $env:USERPROFILE -ChildPath "Documents\cmwt-aad-cred.json") ) Write-Verbose "searching for file: $FilePath" if (Test-Path $FilePath) { $xdata = Get-Content -Path $FilePath -Encoding UTF8 -Raw | ConvertFrom-Json $(New-Object -TypeName PSCredential $xdata.UserName, ($xdata.Password | ConvertTo-SecureString)) } else { Write-Warning "File not found: $FilePath" } } <# .SYNOPSIS Create or Update CMWT configuration settings file .DESCRIPTION Create or Update CMWT configuration settings file .PARAMETER SmsProvider Configuration Manager SMS Provider hostname .PARAMETER SqlHost Configuration Manager site database SQL Server hostname .PARAMETER SiteCode Configuration Manager Site Code .PARAMETER Port TCP Port to run local instance. Default is 8081 .PARAMETER FilePath JSON configuration file path and filename .EXAMPLE Set-CmwtConfigJson -SmsProvider "CM01" -SqlHost "CM01" -SiteCode "P01" -Port 8080 .OUTPUTS JSON file .NOTES JSON file can be edited externally if desired #> function Set-CmwtConfigJson { [CmdletBinding()] param ( [parameter(Mandatory, HelpMessage="ConfigMgr SMS Provider name")] [validateLength(3,32)] [string] $SmsProvider, [parameter(Mandatory, HelpMessage="ConfigMgr SQL Hostname")] [validateLength(3,32)] [string] $SqlHost, [parameter(Mandatory, HelpMessage="ConfigMgr Site Code")] [validateLength(3,3)] [string] $SiteCode, [parameter(HelpMessage="TCP Port Number")] [int] $Port = 8081, [parameter(HelpMessage="Path to Configuration JSON file")] [ValidateNotNullOrEmpty()] [string] $FilePath = $(Join-Path $env:USERPROFILE "documents\cmwt-settings.json"), [parameter()] [switch] $Force ) if (Test-Path $FilePath) { if ($Force) { Write-Verbose "deleting existing file: $FilePath" Get-Item -Path $FilePath | Remove-Item -Force -Confirm:$False } else { Write-Warning "$FilePath exists. To replace, use the -Force parameter." break } } Write-Verbose "saving settings to: $FilePath" @{SMSPROVIDER = $SmsProvider; SQLHOST = $SqlHost; SITECODE = $SiteCode; PORT = $Port} | ConvertTo-Json | Set-Content -Path $FilePath -Encoding UTF8 -Force Write-Output "Settings were saved successfully to $FilePath" } <# .SYNOPSIS Retrieve CMWT configuration settings from JSON file .DESCRIPTION Retrieve CMWT configuration settings from JSON file .PARAMETER FilePath JSON configuration file path and filename .EXAMPLE Get-CmwtConfigJson Returns content from the default JSON file if found .EXAMPLE Get-CmwtConfigJson -FilePath "c:\test\myconfig.json" Returns content from the specified JSON file if found .OUTPUTS Raw contents .NOTES JSON file can be edited externally if desired #> function Get-CmwtConfigJson { [CmdletBinding()] param ( [parameter(HelpMessage="Path to Configuration JSON file")] [ValidateNotNullOrEmpty()] [string] $FilePath = $(Join-Path $env:USERPROFILE "documents\cmwt-settings.json") ) if (Test-Path $FilePath) { Get-Content -Path $FilePath } else { Write-Warning "configuration file not found: $FilePath" } } <# .SYNOPSIS Launch CMWT UniversalDashboard instance .DESCRIPTION Ummmmm, yeah, I just said that. .PARAMETER ConfigJson Path to CMWT configuration JSON file. Default is "($env:USERPROFILE)\documents\cmwt-settings.json" Use the Set-CmwtConfigJson function to create or update a configuration file. .PARAMETER SmsProvider Configuration Manager SMS Provider host name ConfigJson overrides this parameter .PARAMETER SqlHost Configuration Manager site database SQL Server host name ConfigJson overrides this parameter .PARAMETER SiteCode Configuration Manager site code ConfigJson overrides this parameter .PARAMETER Credential AzureAD credentials If omitted, read from AzureAD credentials file .PARAMETER Port TCP port to run CMWT instance. Default is 8081 ConfigJson overrides this parameter .EXAMPLE Start-UDCmwtDashboard Start CMWT using default parameters from configuration file .EXAMPLE Start-UDCmwtDashboard -ConfigJson ".\myconfig.json" Use specified configuration file .EXAMPLE Start-UDCmwtDashboard -SmsProvider "CM01" -SqlHost "CM01" -SiteCode "P01" Start with direct parameter values .OUTPUTS UDDashboard instance: Name, Port, Running, DashboardService .NOTES Tested with UD Community Edition 2.5.3 only #> function Start-UDCmwtDashboard { [CmdletBinding()] param ( [parameter(HelpMessage="Path to Configuration JSON file")] [string] $ConfigJson = $(Join-Path $env:USERPROFILE "documents\cmwt-settings.json"), [parameter(HelpMessage="ConfigMgr SMS Provider name")] [string] $SmsProvider = "", [parameter(HelpMessage="ConfigMgr SQL Hostname")] [string] $SqlHost = "", [parameter(HelpMessage="ConfigMgr Site Code")] [string] $SiteCode = "", [parameter(HelpMessage="AzureAD Credentials")] [pscredential] $Credential, [parameter(HelpMessage="Local Port for CMWT")] [int] $Port = 8081 ) Enable-UDLogging -FilePath "$env:TEMP" if ($null -eq $Credential) { Write-Verbose "ud-cmwt: AzureAD credentials were not provided." Write-Verbose "ud-cmwt: looking for default AzureAD credential file" $Credential = Import-CmwtCredential if ($null -eq $Credential) { Write-Warning "credentials not provided or available in cred-file. Aborting" break } } if (![string]::IsNullOrEmpty($ConfigJson)) { Write-Verbose "ud-cmwt: looking for default site configuration file: $ConfigJson" if (Test-Path $ConfigJson) { Write-Verbose "ud-cmwt: importing local settings file: $ConfigJson" $jdat = Get-Content $ConfigJson -Encoding UTF8 -Raw | ConvertFrom-Json $SmsProvider = $jdat.SMSPROVIDER $SqlHost = $jdat.SQLHOST $SiteCode = $jdat.SITECODE $Port = $jdat.PORT if ([string]::IsNullOrEmpty($SmsProvider) -or ([string]::IsNullOrEmpty($SqlHost)) -or ([string]::IsNullOrEmpty($SiteCode))) { Write-Warning "invalid configuration data. unable to continue." break } else { Write-Verbose "ud-cmwt: successfully imported configuration data" } } else { Write-Warning "file not found: $ConfigJson" Write-Warning "no settings were provided. aborting" break } } if ([string]::IsNullOrEmpty($SmsProvider) -or ([string]::IsNullOrEmpty($SqlHost)) -or ([string]::IsNullOrEmpty($SiteCode))) { Write-Warning "No site parameters provided. unable to continue." break } Write-Verbose "ud-cmwt: enabling and setting global cache" $Cache:Loading = $True $Cache:ConnectionInfo = @{ SmsProvider = $SmsProvider Server = $SqlHost SiteCode = $SiteCode CmDatabase = "CM_$SiteCode" Credential = $Credential BasePath = [string]$(Split-Path ((Get-Module 'ud-cmwt').Path)) QfilePath = [string]$(Join-Path -Path $(Split-Path ((Get-Module 'ud-cmwt').Path)) -ChildPath "cmqueries") } $Cache:CMWT = @{ AppName = "CMWT" AppVersion = [string]$((Get-Module 'ud-cmwt').Version -join '.') AzUsername = $Credential.UserName AzDomain = ($Credential.UserName -split '@')[1] } Import-Module $(Join-Path $PSScriptRoot 'ud-cminit.psm1') Write-Verbose "ud-cmwt: loading pages" $Pages = Get-ChildItem (Join-Path $PSScriptRoot 'pages') -Recurse -File | ForEach-Object { Write-Verbose "loading: $($_.FullName)" & $_.FullName } # $Endpoints = Get-ChildItem (Join-Path $PSScriptRoot 'endpoints') | ForEach-Object { # & $_.FullName # } Write-UDLog -Message $Cache:ConnectionInfo.SmsProvider Write-UDLog -Message $Cache:ConnectionInfo.Server Write-UDLog -Message $Cache:ConnectionInfo.SiteCode Write-UDLog -Message $Cache:ConnectionInfo.CmDatabase #region NavigationMenu Write-Verbose "ud-cmwt: configuring navigation menu" $Navigation = New-UDSideNav -Content { New-UDSideNavItem -Text "Home" -Url "Home" -Icon home New-UDSideNavItem -Text "ConfigMgr" -Icon folder -Children { New-UDSideNavItem -Text "Site Summary" -Url "cmsummary" -Icon database New-UDSideNavItem -Text "Assets" -Icon folder -Children { New-UDSideNavItem -Text "Devices" -Url "cmdevices" -Icon desktop New-UDSideNavItem -Text "Device Collections" -Url "cmdcollections" -Icon desktop New-UDSideNavItem -Text "Users" -Url "cmusers" -Icon user New-UDSideNavItem -Text "User Collections" -Url "cmucollections" -Icon users New-UDSideNavItem -Text "Orchestration Groups" -Url "" -Icon network_wired } New-UDSideNavItem -Text "Software Deploy" -Icon folder -Children { New-UDSideNavItem -Text "Applications" -Url "cmapps" -Icon app_store New-UDSideNavItem -Text "Application Groups" -Url "" -Icon app_store New-UDSideNavItem -Text "Packages" -Url "cmpackages" -Icon app_store New-UDSideNavItem -Text "Scripts" -Url "" -Icon scroll } New-UDSideNavItem -Text "Software Updates" -Icon folder -Children { New-UDSideNavItem -Text "Summary" -Url "cmupdatesummary" -Icon stroopwafel New-UDSideNavItem -Text "Compliance" -Url "cmupdatecompliance" -Icon stroopwafel New-UDSideNavItem -Text "All Updates" -Url "cmupdates" -Icon stroopwafel New-UDSideNavItem -Text "Update Groups" -Url "" -Icon stroopwafel New-UDSideNavItem -Text "Update Packages" -Url "cmupdatepkgs" -Icon stroopwafel New-UDSideNavItem -Text "ADRs" -Url "" -Icon stroopwafel New-UDSideNavItem -Text "3rd Party Catalogs" -Url "" -Icon stroopwafel } New-UDSideNavItem -Text "OS Deploy" -Icon folder -Children { New-UDSideNavItem -Text "OS Images" -Url "cmosimages" -Icon windows New-UDSideNavItem -Text "OS Upgrades" -Url "cmosupgrades" -Icon windows New-UDSideNavItem -Text "Drivers" -Url "" -Icon usb New-UDSideNavItem -Text "Driver Packages" -Url "cmdriverpkgs" -Icon usb New-UDSideNavItem -Text "Boot Images" -Url "cmbootimages" -Icon windows New-UDSideNavItem -Text "Task Sequences" -Url "cmtasksequences" -Icon network_wired New-UDSideNavItem -Text "VHD Packages" -Url "cmvhdpkgs" -Icon gears } New-UDSideNavItem -Text "Hardware Inventory" -Icon folder -Children { New-UDSideNavItem -Text "Group: Models" -Url "" -Icon desktop New-UDSideNavItem -Text "Group: DHCP Servers" -Url "" -Icon network_wired New-UDSideNavItem -Text "Group: IP Subnet" -Url "" -Icon network_wired New-UDSideNavItem -Text "Group: AD Site" -Url "" -Icon network_wired New-UDSideNavItem -Text "Exceptions" -Icon folder -Children { New-UDSideNavItem -Text "Low Disk Space" -Url "" -Icon thermometer New-UDSideNavItem -Text "Old Inventory" -Url "" -Icon clock } } New-UDSideNavItem -Text "Software Inventory" -Icon folder -Children { New-UDSideNavItem -Text "Installed Software" -Url "cmswinventory" -Icon file_contract New-UDSideNavItem -Text "Operating Systems" -Url "" -Icon file_alt New-UDSideNavItem -Text "Installed Hotfixes" -Url "" -Icon file_contract } New-UDSideNavItem -Text "Administration" -Icon folder -Children { New-UDSideNavItem -Text "Discovery Methods" -Url "" -Icon search New-UDSideNavItem -Text "Site Boundaries" -Url "cmboundaries" -Icon city New-UDSideNavItem -Text "Boundary Groups" -Url "cmboundarygroups" -Icon city New-UDSideNavItem -Text "Site Systems" -Url "cmsitesystems" -Icon server New-UDSideNavItem -Text "Site Administrators" -Url "cmadmins" -Icon user_shield New-UDSideNavItem -Text "Certificates" -Url "" -Icon certificate } New-UDSideNavItem -Text "Monitoring" -Icon folder -Children { New-UDSideNavItem -Text "$SmsProvider" -Icon folder -Children { New-UDSideNavItem -Text "Processes" -Url "processes" -Icon tachometer New-UDSideNavItem -Text "Services" -PageName "services" -Icon tachometer New-UDSideNavItem -Text "System Event Log" -PageName "syseventlog" -Icon tachometer New-UDSideNavItem -Text "App Event Log" -PageName "appeventlog" -Icon tachometer } New-UDSideNavItem -Text "$SiteCode - Site Status" -Url "cmsitestatus" -Icon medkit New-UDSideNavItem -Text "$SiteCode - Component Status" -Url "cmcompstatus" -Icon medkit New-UDSideNavItem -Text "$SiteCode - Deployments" -Url "cmdepsummary" -Icon medkit New-UDSideNavItem -Text "SUP Synch Status" -Url "cmsupsynch" -Icon medkit } } # configmgr New-UDSideNavItem -Text "$SiteCode SQL Server" -Icon folder -Children { New-UDSideNavItem -Text "SQL Version" -Url "sqlserverinfo" -Icon database New-UDSideNavItem -Text "Database Files" -Url "sqlfiles" -Icon database New-UDSideNavItem -Text "SQL Agent Jobs" -Url "sqlagentjobs" -Icon database New-UDSideNavItem -Text "Status" -Icon folder -Children { New-UDSideNavItem -Text "SQL Services" -Url "sqlservices" -Icon servicestack New-UDSideNavItem -Text "SQL Agent Job History" -Url "sqlagentjobhistory" -Icon search_location New-UDSideNavItem -Text "Backup History" -Url "sqlbackuphistory" -Icon search_location New-UDSideNavItem -Text "SPN Registrations" -Url "sqlspn" -Icon search_location } New-UDSideNavItem -Text "Performance" -Icon folder -Children { New-UDSideNavItem -Text "Memory Usage" -Url "sqlmem" -Icon search_location New-UDSideNavItem -Text "Fragmentation" -Url "sqlindexfrag" -Icon search_location } New-UDSideNavItem -Text "CM_$SiteCode Database" -Icon folder -Children { New-UDSideNavItem -Text "Views" -Url "dbviews" -Icon table New-UDSideNavItem -Text "Tables" -Url "dbtables" -Icon table } } New-UDSideNavItem -Text "Active Directory" -Icon folder -Children { New-UDSideNavItem -Text "Domain" -Url "addomain" -Icon mountain New-UDSideNavItem -Text "Computers" -Url "adcomputers" -Icon desktop New-UDSideNavItem -Text "Users" -Url "adusers" -Icon users New-UDSideNavItem -Text "Contacts" -Url "" -Icon address_card New-UDSideNavItem -Text "Security Groups" -Url "adgroups" -Icon users_cog New-UDSideNavItem -Text "Print Queues" -Url "adprinters" -Icon print } New-UDSideNavItem -Text "Azure AD" -Icon folder -Children { New-UDSideNavItem -Text "Users" -Url "aadusers" -Icon users New-UDSideNavItem -Text "Groups" -Url "aadgroups" -Icon users_cog New-UDSideNavItem -Text "Devices" -Url "aadcomputers" -Icon desktop New-UDSideNavItem -Text "AAD Portal" -Url "https://aad.portal.azure.com" -Icon microsoft New-UDSideNavItem -Text "AAD Devices Portal" -Url "https://devicemanagement.azure.com" -Icon desktop } New-UDSideNavItem -Text "More..." -Icon folder -Children { New-UDSideNavItem -Text "References" -Url "references" -Icon link New-UDSideNavItem -Text "UD Documentation" -Url "https://docs.universaldashboard.io/" -Icon link New-UDSideNavItem -Text "System Info" -Url "cmwtinfo" -Icon search_plus New-UDSideNavItem -Text "Send Feedback" -Url "https://github.com/Skatterbrainz/ud-cmwt/issues" -Icon comment } New-UDSideNavItem -Text "About" -Url "About" -Icon info_circle } #endregion NavigationMenu Write-Verbose "ud-cmwt: loading dashboard session on port $Port" $Dashboard = New-UDDashboard -Title $Cache:CMWT.AppName -Pages $Pages -Navigation $Navigation Start-UDDashboard -Dashboard $Dashboard -Port $Port } |