diff --git a/.gitignore b/.gitignore index a5d1fca..b4ed384 100644 --- a/.gitignore +++ b/.gitignore @@ -195,3 +195,5 @@ ModelManifest.xml /Atea.Windows.Server.Monitoring/AteaST.snk /Atea.Windows.Service.Monitoring/AteaST.snk /AteaST.snk +VisualStudioAuthoringConsole_x64.msi +_Scripts/VisualStudioAuthoringConsole_x64.msi diff --git a/.vscode/launch.json b/.vscode/launch.json index 6152b72..e69de29 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,13 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "name": "PowerShell", - "type": "PowerShell", - "request": "launch", - "program": "${file}", - "args": [], - "cwd": "${file}" - } - ] -} \ No newline at end of file diff --git a/Atea.Windows.File.Monitoring/Atea.Windows.File.Monitoring.mpproj b/Atea.Windows.File.Monitoring/Atea.Windows.File.Monitoring.mpproj index 68f4001..3b39ac3 100644 --- a/Atea.Windows.File.Monitoring/Atea.Windows.File.Monitoring.mpproj +++ b/Atea.Windows.File.Monitoring/Atea.Windows.File.Monitoring.mpproj @@ -1,12 +1,12 @@  - + Debug {c55b880e-f609-462c-aed3-67f44531d4d7} Atea.Windows.File.Monitoring Atea.Windows.File.Monitoring Atea.Windows.File.Monitoring - 1.0.3.0 + 1.0.3.230 v7.0.2 OM 1.1.0.0 @@ -55,9 +55,16 @@ Code + + Code + Code + + Code + HealthModel\Monitors\FileAge.mptg + Code @@ -67,6 +74,9 @@ Code + + Code + Code @@ -79,12 +89,27 @@ Code + + Code + + + Code + Code Code + + Code + + + Code + + + Code + @@ -106,9 +131,19 @@ - + + + + + + Content + FragmentGenerator + + + + \ No newline at end of file diff --git a/Atea.Windows.File.Monitoring/HealthModel/Discoveries/FileAgeFolderDiscovery.mpx b/Atea.Windows.File.Monitoring/HealthModel/Discoveries/FileAgeFolderDiscovery.mpx new file mode 100644 index 0000000..8582554 --- /dev/null +++ b/Atea.Windows.File.Monitoring/HealthModel/Discoveries/FileAgeFolderDiscovery.mpx @@ -0,0 +1,27 @@ + + + + + Discovery + + + + + $MPElement$ + $Target/Id$ + $Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$ + 14400 + + + + + + + + + Atea FileAge Folder Discovery + + + + + \ No newline at end of file diff --git a/Atea.Windows.File.Monitoring/HealthModel/Discoveries/FileMonitoringSeedDiscovery.mpx b/Atea.Windows.File.Monitoring/HealthModel/Discoveries/FileMonitoringSeedDiscovery.mpx index 1faab85..66c4222 100644 --- a/Atea.Windows.File.Monitoring/HealthModel/Discoveries/FileMonitoringSeedDiscovery.mpx +++ b/Atea.Windows.File.Monitoring/HealthModel/Discoveries/FileMonitoringSeedDiscovery.mpx @@ -15,6 +15,12 @@ 0 0 + + FAgeKeyExist + SOFTWARE\Atea\FileAgeMonitoring + 0 + 0 + 14400 $MPElement[Name="Atea.Windows.File.Monitoring.Seed"]$ @@ -27,15 +33,30 @@ - - - Values/FCKeyExist - - Equal - - true - - + + + + + Values/FCKeyExist + + Equal + + true + + + + + + + Values/FAgeKeyExist + + Equal + + true + + + + diff --git a/Atea.Windows.File.Monitoring/HealthModel/Monitors/FileAge.mptg b/Atea.Windows.File.Monitoring/HealthModel/Monitors/FileAge.mptg new file mode 100644 index 0000000..46aeefc --- /dev/null +++ b/Atea.Windows.File.Monitoring/HealthModel/Monitors/FileAge.mptg @@ -0,0 +1,41 @@ + + + + + Windows.File.FileAge.MonitorType + <TimeoutSeconds>300</TimeoutSeconds><IntervalSeconds>300</IntervalSeconds><FolderFriendlyName>$Target/Property[Type="Atea.Windows.File.FileAgeFolder"]/FriendlyName$</FolderFriendlyName><FileAgeAttribute>$Target/Property[Type="Atea.Windows.File.FileAgeFolder"]/FileAgeAttribute$</FileAgeAttribute> + + + Healthy + No Files Found + Healthy + Success + + + Error + Bad Files Found + Error + Error + + + Health!System.Health.AvailabilityState + Public + FileAgeMonitor + File Age Monitor + This monitor will look for files in a folder, recursively if configured so, and alert if one of more files are found. + Atea.Windows.File.FileAgeFolder + true + AvailabilityHealth + true + Normal + true + Error + Normal + MatchMonitorHealth + Files with bad timestamp found + $Data/Context/Property[@Name="Summary"]$ + false + + + + \ No newline at end of file diff --git a/Atea.Windows.File.Monitoring/HealthModel/Monitors/FileAge.mptg.mpx b/Atea.Windows.File.Monitoring/HealthModel/Monitors/FileAge.mptg.mpx new file mode 100644 index 0000000..62145de Binary files /dev/null and b/Atea.Windows.File.Monitoring/HealthModel/Monitors/FileAge.mptg.mpx differ diff --git a/Atea.Windows.File.Monitoring/Scripts/AteaFCTPSPropertyBag.ps1 b/Atea.Windows.File.Monitoring/Scripts/AteaFCTPSPropertyBag.ps1 deleted file mode 100644 index 5612c44..0000000 --- a/Atea.Windows.File.Monitoring/Scripts/AteaFCTPSPropertyBag.ps1 +++ /dev/null @@ -1,69 +0,0 @@ -# Begin with getting all the subkeys -# http://technet.microsoft.com/en-us/library/ff730937.aspx -# http://powershell.com/cs/blogs/tips/archive/2009/12/03/dynamically-create-script-blocks.aspx -# http://technet.microsoft.com/sv-se/library/ee176852(en-us).aspx - -$RegistryPath = "hklm:\Software\Atea\FileCreation\" -$EventLogSourceName = "Atea FCT Monitor" -$SubKeys = Get-ChildItem $RegistryPath -$OpsmgrAPI = New-Object -ComObject "MOM.ScriptAPI" -if (![System.Diagnostics.EventLog]::SourceExists($EventLogSourceName)) -{ - New-EventLog -Source $EventLogSourceName -logname "Application" -} -ForEach ($SubKey in $SubKeys) -{ - $FriendlyName = ($SubKey.Name.Substring($SubKey.Name.LastIndexOfAny("\")+1)) - $FolderPath = $SubKey.GetValue("FolderPath") - $Recursive = $SubKey.GetValue("Recursive") - $FilePattern = $SubKey.GetValue("FilePattern") - $AgeInMinutes = $SubKey.GetValue("AgeInMinutes") - $Operator = $SubKey.GetValue("Operator") - - if (($FolderPath -ne $null) -and ($Recursive -ne $null) -and ($FilePattern -ne $null) -and ($AgeInMinutes -ne $null) -and ($Operator -ne $null)) - { - $Operator = $Operator.Trim() - - switch ($Operator) - { - "<" {$Operator = "-lt"} - "<=" {$Operator = "-le"} - ">" {$Operator = "-gt"} - ">=" {$Operator = "-ge"} - default {$Operator = "-gt"} - } - - if ($Recursive.Trim() -eq "false") - { - $Recursive = "" - } else { - $Recursive = "-Recurse " - } - - $command = "Get-ChildItem $FolderPath $Recursive| where {(`$_.Name -like '$FilePattern') -and ((((Get-Date) - `$_.CreationTime).TotalMinutes) $Operator $AgeInMinutes)}" - $ScriptBlock = $ExecutionContext.InvokeCommand.NewScriptBlock($command) - #$command - $Files = @(Invoke-Command -ScriptBlock $ScriptBlock) - If ($Files.Count -gt 0) - { - ForEach ($File in $Files) - { - $FileName = $File.Name - $FileFullname = $File.FullName - $FileCreationTime = $File.CreationTime - $FileAgeMinutes = [math]::Round(((Get-Date) - $FileCreationTime).TotalMinutes,0) - - #Add values to propertybag for monitoring - $propertyBag = $OpsmgrAPI.CreatePropertyBag() - $propertyBag.AddValue("FileName",$FileName) - $propertyBag.AddValue("FileFullname",$FileFullname) - $propertyBag.AddValue("FileCreationTime",$FileCreationTime) - $propertyBag.AddValue("FileAgeMinutes",$FileAgeMinutes) - $propertyBag.AddValue("FolderFriendlyName",$FriendlyName) - - $propertyBag - Write-EventLog -LogName "Application" -Source $EventLogSourceName -EventID "400" -Message "Filename: $FileName `nFilepath: $FileFullname `nFileAge: $FileAgeMinutes minutes`nFileCreationTime: $FileCreationTime `n`nFolder FriendlyName=$FriendlyName" - } - } - } -} diff --git a/Atea.Windows.File.Monitoring/Scripts/AteaFileCreationTimePoSHDiscovery.ps1 b/Atea.Windows.File.Monitoring/Scripts/AteaFileCreationTimePoSHDiscovery.ps1 index 5077f7a..0c4b3d8 100644 --- a/Atea.Windows.File.Monitoring/Scripts/AteaFileCreationTimePoSHDiscovery.ps1 +++ b/Atea.Windows.File.Monitoring/Scripts/AteaFileCreationTimePoSHDiscovery.ps1 @@ -7,9 +7,9 @@ param([string]$sourceId, [string]$managedEntityId, [string]$computerName) $RegistryPath = "hklm:\Software\Atea\FileCreationTime\" $SubKeys = Get-ChildItem $RegistryPath -$OpsmgrAPI = New-Object -ComObject "MOM.ScriptAPI" -#$OpsmgrAPI.LogScriptEvent("AteaFilCreationPoSHDiscovery.ps1", 242, 4, "Running File Creation Folder discovery with parameters $sourceId, $managedEntityId, $computerName") -$discoveryData = $OpsmgrAPI.CreateDiscoveryData(0, $sourceId, $managedEntityId) +$omApi = New-Object -ComObject "MOM.ScriptAPI" +#$omApi.LogScriptEvent("AteaFilCreationPoSHDiscovery.ps1", 242, 4, "Running File Creation Folder discovery with parameters $sourceId, $managedEntityId, $computerName") +$discoveryData = $omApi.CreateDiscoveryData(0, $sourceId, $managedEntityId) ForEach ($SubKey in $SubKeys) { $FriendlyName = ($SubKey.Name.Substring($SubKey.Name.LastIndexOfAny("\")+1)) @@ -18,12 +18,12 @@ ForEach ($SubKey in $SubKeys) $FilePattern = $SubKey.GetValue("FilePattern") $AgeInMinutes = $SubKey.GetValue("AgeInMinutes") $Operator = $SubKey.GetValue("Operator") - - + + if (($FolderPath -ne $null) -and ($Recursive -ne $null) -and ($FilePattern -ne $null) -and ($AgeInMinutes -ne $null) -and ($Operator -ne $null)) { $Operator = $Operator.Trim() - + #Add values to property bag for Discovery $discoveryInstance = $discoveryData.CreateClassInstance("$MPElement[Name='Atea.Windows.File.FileCreationTimeFolder']$") $discoveryInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $computerName) diff --git a/Atea.Windows.File.Monitoring/Scripts/FileAgePB.ps1 b/Atea.Windows.File.Monitoring/Scripts/FileAgePB.ps1 new file mode 100644 index 0000000..85a3afa --- /dev/null +++ b/Atea.Windows.File.Monitoring/Scripts/FileAgePB.ps1 @@ -0,0 +1,107 @@ +# Begin with getting all the subkeys +# http://technet.microsoft.com/en-us/library/ff730937.aspx +# http://powershell.com/cs/blogs/tips/archive/2009/12/03/dynamically-create-script-blocks.aspx +# http://technet.microsoft.com/sv-se/library/ee176852(en-us).aspx + +[CmdletBinding()] +Param( + [ValidateSet("CreationTime","LastWriteTime","LastAccessTime")] + [Parameter(Mandatory=$true)] + [string] $FileAgeAttribute +) + +$RegistryPath = "hklm:\Software\Atea\FileAgeMonitoring\" +$EventLogSourceName = "Atea FileAge Monitor" +$omApi = New-Object -ComObject "MOM.ScriptAPI" +if (![System.Diagnostics.EventLog]::SourceExists($EventLogSourceName)) { + New-EventLog -Source $EventLogSourceName -logname "Application" +} + +if (Test-Path -Path $RegistryPath) { + # Yes, we can read from $RegistryPath + $SubKeys = Get-ChildItem $RegistryPath + + if ($SubKeys -ne $null) { + # Found configuration keys, processing folders + ForEach ($SubKey in $SubKeys) { + $FriendlyName = ($SubKey.Name.Substring($SubKey.Name.LastIndexOfAny("\")+1)) + $FolderPath = $SubKey.GetValue("FolderPath") + $Recursive = $SubKey.GetValue("Recursive") + $FilePattern = $SubKey.GetValue("FilePattern") + $AgeInMinutes = $SubKey.GetValue("AgeInMinutes") + $Operator = $SubKey.GetValue("Operator") + # $AgeAttribute = $SubKey.GetValue("FileAgeAttribute") # Don't know if I really need this + + if (($FolderPath -ne $null) -and ($Recursive -ne $null) -and ($FilePattern -ne $null) -and ($AgeInMinutes -ne $null) -and ($Operator -ne $null)) { + $Operator = $Operator.Trim() + + switch ($Operator) + { + "<" {$Operator = "-lt"} + "<=" {$Operator = "-le"} + ">" {$Operator = "-gt"} + ">=" {$Operator = "-ge"} + default {$Operator = "-gt"} + } + + $summaryMessage = "File Age Monitor on '$FriendlyName', looking for '$FilePattern' where $FileAgeAttribute $Operator $AgeInMinutes in $FolderPath" + + if ($Recursive.Trim() -eq "false") + { + $Recursive = "" + $summaryMessage += "`n`n" + } else { + $Recursive = "-Recurse " + $summaryMessage += ", Recursive`n`n" + } + + $command = "Get-ChildItem $FolderPath $Recursive -Attributes !Directory | where {(`$_.Name -like '$FilePattern') -and ((((Get-Date) - `$_.$FileAgeAttribute).TotalMinutes) $Operator $AgeInMinutes)}" + $ScriptBlock = $ExecutionContext.InvokeCommand.NewScriptBlock($command) + $Files = @(Invoke-Command -ScriptBlock $ScriptBlock) #DevSkim: ignore DS104456 + if ($Files.Count -gt 0) { + $summaryMessage += "Found $($Files.Count) matching files:`n" + #$summaryMessage += "File Name`tFile Path`t`tAge (minutes)`tTimeStamp`n" + ForEach ($File in $Files) + { + $FileName = $File.Name + $FileFullname = $File.FullName + switch ($FileAgeAttribute) { + "CreationTime" {$FileDateTime = $File.CreationTime} + "LastWriteTime" {$FileDateTime = $File.LastWriteTime} + "LastAccessTime" {$FileDateTime = $File.LastAccessTime} + } + $FileAgeMinutes = [math]::Round(((Get-Date) - $FileDateTime).TotalMinutes,0) + $summaryMessage += "$FileName`n`tMinutes since $($FileAgeAttribute): $FileAgeMinutes`n`tTimestamp: $($FileDateTime -f "o")`n`tFile Path: $FileFullName`n`n" + } + #We have old files, and a message. Build the property bag + $propertyBag = $omApi.CreatePropertyBag() + $propertyBag.AddValue("FolderFriendlyName",$FriendlyName) + $propertyBag.AddValue("Summary",$summaryMessage) + $propertyBag.AddValue("FileCount",$Files.Count) + + $propertyBag + Write-EventLog -LogName "Application" -Source $EventLogSourceName -EventID "400" -Message $summaryMessage -EntryType Information -Category 0 + + } else { + # No matching files found + $propertyBag = $omApi.CreatePropertyBag() + $propertyBag.AddValue("FolderFriendlyName",$FriendlyName) + $propertyBag.AddValue("Summary",$summaryMessage) + $propertyBag.AddValue("FileCount",$Files.Count) + + $propertyBag + } + } + } + } else { + # Registry does not contain any configured File Age Monitoring + # or we don't have access to read the keys + $propertyBag = $omApi.CreatePropertyBag() + $propertyBag + } +} else { + #Nope, not able to read from the registry path + Write-EventLog -LogName "Application" -Source $EventLogSourceName -EventID "404" -Message "$RegistryPath is not found on this system, unable to read file age monitoring configuration.`n`nReturning an empty property bag." -EntryType Error -Category 0 + $propertyBag = $omApi.CreatePropertyBag() + $propertyBag +} \ No newline at end of file diff --git a/Atea.Windows.File.Monitoring/Scripts/FileAgePoSHDiscovery.ps1 b/Atea.Windows.File.Monitoring/Scripts/FileAgePoSHDiscovery.ps1 new file mode 100644 index 0000000..baae1f6 --- /dev/null +++ b/Atea.Windows.File.Monitoring/Scripts/FileAgePoSHDiscovery.ps1 @@ -0,0 +1,53 @@ +# Begin with getting all the subkeys +# http://technet.microsoft.com/en-us/library/ff730937.aspx +# http://powershell.com/cs/blogs/tips/archive/2009/12/03/dynamically-create-script-blocks.aspx +# http://technet.microsoft.com/sv-se/library/ee176852(en-us).aspx + +param([string]$sourceId, [string]$managedEntityId, [string]$computerName) + +$EventLogSourceName = "Atea FileAge Monitor" +$eventlogMessage = "Running FileAgeFolder discovery.`n" +$eventlogMessage += "Params:`n`tsourceId=$sourceId`n`tmanagedEntityId=$managedEntityId`n`tcomputerName=$computerName`n`n" +if (![System.Diagnostics.EventLog]::SourceExists($EventLogSourceName)) { + New-EventLog -Source $EventLogSourceName -logname "Application" +} + +$RegistryPath = "hklm:\Software\Atea\FileAgeMonitoring\" +$omApi = New-Object -ComObject "MOM.ScriptAPI" +$discoveryData = $omApi.CreateDiscoveryData(0, $sourceId, $managedEntityId) +if (Test-Path -Path $RegistryPath) { + # Registry path is accessible + $SubKeys = Get-ChildItem $RegistryPath + ForEach ($SubKey in $SubKeys) + { + $FriendlyName = ($SubKey.Name.Substring($SubKey.Name.LastIndexOfAny("\")+1)) + $FolderPath = $SubKey.GetValue("FolderPath") + $Recursive = $SubKey.GetValue("Recursive") + $FilePattern = $SubKey.GetValue("FilePattern") + $AgeInMinutes = $SubKey.GetValue("AgeInMinutes") + $Operator = $SubKey.GetValue("Operator") + $FileAgeAttribute = $SubKey.GetValue("FileAgeAttribute") + + + if (($FolderPath -ne $null) -and ($Recursive -ne $null) -and ($FilePattern -ne $null) -and ($AgeInMinutes -ne $null) -and ($Operator -ne $null) -and ($FileAgeAttribute -ne $null)) + { + $Operator = $Operator.Trim() + + #Add values to property bag for Discovery + $discoveryInstance = $discoveryData.CreateClassInstance("$MPElement[Name='Atea.Windows.File.FileAgeFolder']$") + $discoveryInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $computerName) + $discoveryInstance.AddProperty("$MPElement[Name='Atea.Windows.File.FileAgeFolder']/FriendlyName$",$FriendlyName) + $discoveryInstance.AddProperty("$MPElement[Name='Atea.Windows.File.FileAgeFolder']/FolderPath$",$FolderPath) + $discoveryInstance.AddProperty("$MPElement[Name='Atea.Windows.File.FileAgeFolder']/Recursive$",$Recursive) + $discoveryInstance.AddProperty("$MPElement[Name='Atea.Windows.File.FileAgeFolder']/FilePattern$",$FilePattern) + $discoveryInstance.AddProperty("$MPElement[Name='Atea.Windows.File.FileAgeFolder']/AgeInMinutes$",$AgeInMinutes) + $discoveryInstance.AddProperty("$MPElement[Name='Atea.Windows.File.FileAgeFolder']/Operator$",$Operator) + $discoveryInstance.AddProperty("$MPElement[Name='Atea.Windows.File.FileAgeFolder']/FileAgeAttribute$",$FileAgeAttribute) + $discoveryData.AddInstance($discoveryInstance) + $eventlogMessage += "- Added $($FriendlyName) to discovery data`n" + } + } +} + +Write-EventLog -LogName "Application" -Source $EventLogSourceName -EventID "200" -Message "" -EntryType Information -Category 0 +$discoveryData diff --git a/Atea.Windows.File.Monitoring/ServiceModel/Classes/FileAgeFolder.mpx b/Atea.Windows.File.Monitoring/ServiceModel/Classes/FileAgeFolder.mpx new file mode 100644 index 0000000..4c33777 --- /dev/null +++ b/Atea.Windows.File.Monitoring/ServiceModel/Classes/FileAgeFolder.mpx @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + Atea File Age Folder + + + + + + Folder Path + + + + Recursive Check + + + + + + File Pattern + + + + Age in Minutes + + + + Operator + + + + Friendly Name + + + + File Age Attribute + + + + + + diff --git a/Atea.Windows.File.Monitoring/TypeLibrary/ModuleTypes/DataSources/FileAgeFolderDiscoveryDS.mpx b/Atea.Windows.File.Monitoring/TypeLibrary/ModuleTypes/DataSources/FileAgeFolderDiscoveryDS.mpx new file mode 100644 index 0000000..a3c21a4 --- /dev/null +++ b/Atea.Windows.File.Monitoring/TypeLibrary/ModuleTypes/DataSources/FileAgeFolderDiscoveryDS.mpx @@ -0,0 +1,56 @@ + + + + + + + Health!System.Health.AlertSchema + + + + + + + + + + + + + + + + $Config/IntervalSeconds$ + + + + + + $Config/MPElement$ + $Config/TargetID$ + $Config/ComputerName$ + + + + + + + + + + System!System.Discovery.Data + + + + + + + + Atea File Age Folder Discovery Data Source + This datasource provides the basic discovery data for the watched folders. + + + + + + diff --git a/Atea.Windows.File.Monitoring/TypeLibrary/ModuleTypes/DataSources/FileAgePropertyBagDS.mpx b/Atea.Windows.File.Monitoring/TypeLibrary/ModuleTypes/DataSources/FileAgePropertyBagDS.mpx new file mode 100644 index 0000000..6df853f --- /dev/null +++ b/Atea.Windows.File.Monitoring/TypeLibrary/ModuleTypes/DataSources/FileAgePropertyBagDS.mpx @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + $Config/IntervalSeconds$ + + + + + + $Config/FileAgeAttribute$ + $Config/TimeoutSeconds$ + + + + + + Property[@Name='FolderFriendlyName'] + + Equal + + $Config/FolderFriendlyName$ + + + + + + + + + + + + + + + System!System.PropertyBagData + + + + + + + + Atea Windows File - File Age PropertyBag Data Source + + + + + diff --git a/Atea.Windows.File.Monitoring/TypeLibrary/ModuleTypes/ProbeActions/FileAgeFolderDiscoveryProbe.mpx b/Atea.Windows.File.Monitoring/TypeLibrary/ModuleTypes/ProbeActions/FileAgeFolderDiscoveryProbe.mpx new file mode 100644 index 0000000..4828577 --- /dev/null +++ b/Atea.Windows.File.Monitoring/TypeLibrary/ModuleTypes/ProbeActions/FileAgeFolderDiscoveryProbe.mpx @@ -0,0 +1,47 @@ + + + + + + + Windows!Microsoft.Windows.PowerShellSchema + System!System.ParamListSchema + + + + + + + + + + FileAgePoSHDiscovery.ps1 + $IncludeFileContent/Scripts/FileAgePoSHDiscovery.ps1$ + + + sourceId + $Config/MPElement$ + + + managedEntityId + $Config/TargetID$ + + + ComputerName + $Config/ComputerName$ + + + 300 + + + + + + + + System!System.Discovery.Data + System!System.TriggerData + + + + diff --git a/Atea.Windows.File.Monitoring/TypeLibrary/ModuleTypes/ProbeActions/FileAgePoSHProbe.mpx b/Atea.Windows.File.Monitoring/TypeLibrary/ModuleTypes/ProbeActions/FileAgePoSHProbe.mpx new file mode 100644 index 0000000..509528b --- /dev/null +++ b/Atea.Windows.File.Monitoring/TypeLibrary/ModuleTypes/ProbeActions/FileAgePoSHProbe.mpx @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + FileAgePB.ps1 + $IncludeFileContent/Scripts/FileAgePB.ps1$ + + + + FileAgeAttribute + $Config/FileAgeAttribute$ + + + $Config/TimeoutSeconds$ + + + + + + + + System!System.PropertyBagData + true + + + + diff --git a/Atea.Windows.File.Monitoring/TypeLibrary/MonitorTypes/FileAgeMonitoryType.mpx b/Atea.Windows.File.Monitoring/TypeLibrary/MonitorTypes/FileAgeMonitoryType.mpx new file mode 100644 index 0000000..2c6f7b7 --- /dev/null +++ b/Atea.Windows.File.Monitoring/TypeLibrary/MonitorTypes/FileAgeMonitoryType.mpx @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + $Config/TimeoutSeconds$ + $Config/IntervalSeconds$ + $Config/FolderFriendlyName$ + $Config/FileAgeAttribute$ + + + $Config/FileAgeAttribute$ + $Config/TimeoutSeconds$ + + + + + + Property[@Name='FolderFriendlyName'] + + Equal + + $Config/FolderFriendlyName$ + + + + + + + + + Property[@Name='FileCount'] + + NotEqual + + 0 + + + + + + + + + Property[@Name='FileCount'] + + Equal + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Atea.Windows.Installer/Atea.Windows.Installer.vdproj b/Atea.Windows.Installer/Atea.Windows.Installer.vdproj index a9ae84c..9226cb4 100644 --- a/Atea.Windows.Installer/Atea.Windows.Installer.vdproj +++ b/Atea.Windows.Installer/Atea.Windows.Installer.vdproj @@ -46,19 +46,19 @@ "Entry" { "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_53950D255F9649DC80B517E8902CA97A" + "OwnerKey" = "8:_C58F4C60AE9D4646B6B73E6E83A7F892" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_C58F4C60AE9D4646B6B73E6E83A7F892" + "OwnerKey" = "8:_989F92A89DCC4C05A2671096BBB0BFB7" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_989F92A89DCC4C05A2671096BBB0BFB7" + "OwnerKey" = "8:_53950D255F9649DC80B517E8902CA97A" "MsmSig" = "8:_UNDEFINED" } } @@ -79,6 +79,22 @@ "PrivateKeyFile" = "8:" "TimeStampServer" = "8:" "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + "Items" + { + "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.5" + { + "Name" = "8:Microsoft .NET Framework 4.5 (x86 and x64)" + "ProductCode" = "8:.NETFramework,Version=v4.5" + } + } + } } "Release" { @@ -100,7 +116,7 @@ "Enabled" = "11:FALSE" "PromptEnabled" = "11:TRUE" "PrerequisitesLocation" = "2:1" - "Url" = "8:" + "Url" = "8:https://github.com/stegenfeldt/Atea.Windows/raw/master/Released/Atea.Windows.Installer.msi" "ComponentsUrl" = "8:" "Items" { @@ -139,7 +155,7 @@ { "AssemblyRegister" = "3:1" "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Atea.Windows.File.Monitoring, Version=1.0.3.2, Culture=neutral, PublicKeyToken=62373e1518b7f72f, processorArchitecture=MSIL" + "AssemblyAsmDisplayName" = "8:Atea.Windows.File.Monitoring, Version=1.0.3.101, Culture=neutral, PublicKeyToken=62373e1518b7f72f, processorArchitecture=MSIL" "ScatterAssemblies" { "_4E738A19F12B461CB0E1656840A98197" @@ -170,7 +186,7 @@ { "AssemblyRegister" = "3:1" "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Atea.Windows.Service.Monitoring, Version=1.0.3.2, Culture=neutral, PublicKeyToken=62373e1518b7f72f, processorArchitecture=MSIL" + "AssemblyAsmDisplayName" = "8:Atea.Windows.Service.Monitoring, Version=1.0.3.101, Culture=neutral, PublicKeyToken=62373e1518b7f72f, processorArchitecture=MSIL" "ScatterAssemblies" { "_53950D255F9649DC80B517E8902CA97A" @@ -201,7 +217,7 @@ { "AssemblyRegister" = "3:1" "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Atea.Windows.Library, Version=1.0.3.2, Culture=neutral, PublicKeyToken=62373e1518b7f72f, processorArchitecture=MSIL" + "AssemblyAsmDisplayName" = "8:Atea.Windows.Library, Version=1.0.3.101, Culture=neutral, PublicKeyToken=62373e1518b7f72f, processorArchitecture=MSIL" "ScatterAssemblies" { "_989F92A89DCC4C05A2671096BBB0BFB7" @@ -232,7 +248,7 @@ { "AssemblyRegister" = "3:1" "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Atea.Windows.Server.Monitoring, Version=1.0.3.2, Culture=neutral, PublicKeyToken=62373e1518b7f72f, processorArchitecture=MSIL" + "AssemblyAsmDisplayName" = "8:Atea.Windows.Server.Monitoring, Version=1.0.3.220, Culture=neutral, PublicKeyToken=62373e1518b7f72f, processorArchitecture=MSIL" "ScatterAssemblies" { "_C58F4C60AE9D4646B6B73E6E83A7F892" @@ -349,7 +365,7 @@ "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:Atea Windows - MP Package" "ProductCode" = "8:{0BDBCC52-6F5E-4844-8E96-C05705F5A9FA}" - "PackageCode" = "8:{4189E1E6-7136-47BE-85C9-CE753796406C}" + "PackageCode" = "8:{FB70A253-AD22-4DBB-B7BB-156FA67B24C3}" "UpgradeCode" = "8:{44CB4EA9-89BB-4063-91FA-3CC9EA76F800}" "AspNetVersion" = "8:4.0.30319.0" "RestartWWWService" = "11:FALSE" @@ -362,7 +378,7 @@ "ARPHELPLINK" = "8:https://github.com/stegenfeldt/Atea.Windows/issues" "Title" = "8:Atea.Windows.Installer" "Subject" = "8:" - "ARPCONTACT" = "8:Samuel Tegenfledt - Atea Sverige AB" + "ARPCONTACT" = "8:Samuel Tegenfeldt - Atea Sverige AB" "Keywords" = "8:OpsMgr, System Center, Management Pack" "ARPCOMMENTS" = "8:" "ARPURLINFOABOUT" = "8:" diff --git a/Atea.Windows.Library/Atea.Windows.Library.mpproj b/Atea.Windows.Library/Atea.Windows.Library.mpproj index 891c9de..afd26b5 100644 --- a/Atea.Windows.Library/Atea.Windows.Library.mpproj +++ b/Atea.Windows.Library/Atea.Windows.Library.mpproj @@ -1,12 +1,12 @@  - + Debug {361e64de-7730-493d-8464-c22911eb5791} Atea.Windows Atea.Windows.Library Atea.Windows.Library - 1.0.3.0 + 1.0.3.230 v7.0 OM 1.1.0.0 @@ -33,28 +33,30 @@ SC - false + False Windows - false + False Health - false + False System - false + False Visualization - false + False + + @@ -66,6 +68,54 @@ Content FragmentGenerator + + Content + + + Content + + + Content + + + Content + + + Content + + + Content + + + Content + + + Content + + + Content + + + Content + + + Content + + + Content + + + Content + + + Content + + + Content + + + Content + @@ -82,5 +132,9 @@ Code + + + + \ No newline at end of file diff --git a/Atea.Windows.Library/Resources/Images/icons8-event-log-16.png b/Atea.Windows.Library/Resources/Images/icons8-event-log-16.png new file mode 100644 index 0000000..31dfc48 Binary files /dev/null and b/Atea.Windows.Library/Resources/Images/icons8-event-log-16.png differ diff --git a/Atea.Windows.Library/Resources/Images/icons8-event-log-32.png b/Atea.Windows.Library/Resources/Images/icons8-event-log-32.png new file mode 100644 index 0000000..6238163 Binary files /dev/null and b/Atea.Windows.Library/Resources/Images/icons8-event-log-32.png differ diff --git a/Atea.Windows.Library/Resources/Images/icons8-event-log-48.png b/Atea.Windows.Library/Resources/Images/icons8-event-log-48.png new file mode 100644 index 0000000..dd0751b Binary files /dev/null and b/Atea.Windows.Library/Resources/Images/icons8-event-log-48.png differ diff --git a/Atea.Windows.Library/Resources/Images/icons8-file-preview-16.png b/Atea.Windows.Library/Resources/Images/icons8-file-preview-16.png new file mode 100644 index 0000000..13d977d Binary files /dev/null and b/Atea.Windows.Library/Resources/Images/icons8-file-preview-16.png differ diff --git a/Atea.Windows.Library/Resources/Images/icons8-file-preview-32.png b/Atea.Windows.Library/Resources/Images/icons8-file-preview-32.png new file mode 100644 index 0000000..f3f0d0c Binary files /dev/null and b/Atea.Windows.Library/Resources/Images/icons8-file-preview-32.png differ diff --git a/Atea.Windows.Library/Resources/Images/icons8-file-preview-48.png b/Atea.Windows.Library/Resources/Images/icons8-file-preview-48.png new file mode 100644 index 0000000..bf6ebc1 Binary files /dev/null and b/Atea.Windows.Library/Resources/Images/icons8-file-preview-48.png differ diff --git a/Atea.Windows.Library/Resources/Images/icons8-gear-outline-100.png b/Atea.Windows.Library/Resources/Images/icons8-gear-outline-100.png new file mode 100644 index 0000000..4fad7b0 Binary files /dev/null and b/Atea.Windows.Library/Resources/Images/icons8-gear-outline-100.png differ diff --git a/Atea.Windows.Library/Resources/Images/icons8-gear-outline-16.png b/Atea.Windows.Library/Resources/Images/icons8-gear-outline-16.png new file mode 100644 index 0000000..033e8bb Binary files /dev/null and b/Atea.Windows.Library/Resources/Images/icons8-gear-outline-16.png differ diff --git a/Atea.Windows.Library/Resources/Images/icons8-gear-outline-32.png b/Atea.Windows.Library/Resources/Images/icons8-gear-outline-32.png new file mode 100644 index 0000000..643ec77 Binary files /dev/null and b/Atea.Windows.Library/Resources/Images/icons8-gear-outline-32.png differ diff --git a/Atea.Windows.Library/Resources/Images/icons8-gear-outline-48.png b/Atea.Windows.Library/Resources/Images/icons8-gear-outline-48.png new file mode 100644 index 0000000..fd8d7bb Binary files /dev/null and b/Atea.Windows.Library/Resources/Images/icons8-gear-outline-48.png differ diff --git a/Atea.Windows.Library/Resources/Images/icons8-server-16.png b/Atea.Windows.Library/Resources/Images/icons8-server-16.png new file mode 100644 index 0000000..58a1279 Binary files /dev/null and b/Atea.Windows.Library/Resources/Images/icons8-server-16.png differ diff --git a/Atea.Windows.Library/Resources/Images/icons8-server-32.png b/Atea.Windows.Library/Resources/Images/icons8-server-32.png new file mode 100644 index 0000000..de878f4 Binary files /dev/null and b/Atea.Windows.Library/Resources/Images/icons8-server-32.png differ diff --git a/Atea.Windows.Library/Resources/Images/icons8-server-48.png b/Atea.Windows.Library/Resources/Images/icons8-server-48.png new file mode 100644 index 0000000..c6ba0d0 Binary files /dev/null and b/Atea.Windows.Library/Resources/Images/icons8-server-48.png differ diff --git a/Atea.Windows.Library/Resources/Images/icons8-windows-light-client-16.png b/Atea.Windows.Library/Resources/Images/icons8-windows-light-client-16.png new file mode 100644 index 0000000..86be093 Binary files /dev/null and b/Atea.Windows.Library/Resources/Images/icons8-windows-light-client-16.png differ diff --git a/Atea.Windows.Library/Resources/Images/icons8-windows-light-client-32.png b/Atea.Windows.Library/Resources/Images/icons8-windows-light-client-32.png new file mode 100644 index 0000000..40568ce Binary files /dev/null and b/Atea.Windows.Library/Resources/Images/icons8-windows-light-client-32.png differ diff --git a/Atea.Windows.Library/Resources/Images/icons8-windows-light-client-48.png b/Atea.Windows.Library/Resources/Images/icons8-windows-light-client-48.png new file mode 100644 index 0000000..b0b4ecf Binary files /dev/null and b/Atea.Windows.Library/Resources/Images/icons8-windows-light-client-48.png differ diff --git a/Atea.Windows.Server.Monitoring/Atea.Windows.Server.Monitoring.mpproj b/Atea.Windows.Server.Monitoring/Atea.Windows.Server.Monitoring.mpproj index 2514623..e883e35 100644 --- a/Atea.Windows.Server.Monitoring/Atea.Windows.Server.Monitoring.mpproj +++ b/Atea.Windows.Server.Monitoring/Atea.Windows.Server.Monitoring.mpproj @@ -1,12 +1,12 @@  - + Debug {e346d1c7-2ca1-4e15-a871-663f747fbfde} Atea.Windows.Server.Monitoring Atea.Windows.Server.Monitoring Atea.Windows.Server.Monitoring - 1.0.3.0 + 1.0.3.230 v7.0 OM 1.1.0.0 @@ -62,19 +62,58 @@ + + Content + FragmentGenerator + + + Content + FragmentGenerator + + + Content + FragmentGenerator + Content FragmentGenerator + + Code + HealthModel\Discoveries\Discoveries.mptg + + + Code + HealthModel\Monitors\AggregateMonitors.mptg + + + Code + HealthModel\Monitors\EventMonitoring.mptg + Code HealthModel\Rules\PerformanceCollection.mptg + + Code + Code + + Code + + + Code + + + Code + + + Code + @@ -86,11 +125,25 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Atea.Windows.Server.Monitoring/HealthModel/Discoveries/Discoveries.mptg b/Atea.Windows.Server.Monitoring/HealthModel/Discoveries/Discoveries.mptg new file mode 100644 index 0000000..76724b0 --- /dev/null +++ b/Atea.Windows.Server.Monitoring/HealthModel/Discoveries/Discoveries.mptg @@ -0,0 +1,100 @@ + + + + + MonitoredEventDiscovery + Monitored Event Discovery + Discover "MonitoredEvent" instances based on registry information. + DS + <IntervalSeconds>3600</IntervalSeconds><SyncTime /><ScriptName>Get-MonitoredEventDiscoveryDS.ps1</ScriptName><ScriptBody>$IncludeFileContent/Scripts/Get-MonitoredEventDiscoveryDS.ps1$</ScriptBody><Parameters><Parameter><Name>computerName</Name><Value>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Value></Parameter></Parameters><TimeoutSeconds>120</TimeoutSeconds> + Windows!Microsoft.Windows.TimedPowerShell.DiscoveryProvider + Atea.Windows.Server.Monitoring.MonitoredEventSeed + true + true + Normal + false + Discovery + + + Atea.Windows.Server.Monitoring.MonitoredEvent + + + Atea.Windows.Server.Monitoring.MonitoredEvent + EventMonitorName + + + Atea.Windows.Server.Monitoring.MonitoredEvent + ErrorEventId + + + Atea.Windows.Server.Monitoring.MonitoredEvent + ErrorEventLevel + + + Atea.Windows.Server.Monitoring.MonitoredEvent + ErrorEventSource + + + Atea.Windows.Server.Monitoring.MonitoredEvent + ErrorEventLog + + + Atea.Windows.Server.Monitoring.MonitoredEvent + HealthyEventId + + + Atea.Windows.Server.Monitoring.MonitoredEvent + HealthyEventLevel + + + Atea.Windows.Server.Monitoring.MonitoredEvent + HealthyEventSource + + + Atea.Windows.Server.Monitoring.MonitoredEvent + HealthyEventLog + + + Atea.Windows.Server.Monitoring.MonitoredEvent + ShortDescription + + + System!System.Entity + DisplayName + + + + + + + Atea.Windows.Server.Monitoring.ComputerHostsMonitoredEvent + + + + + + + + MonitoredEventSeedDiscovery + Monitored Event Seed Discovery + Registry-based discovery to find Monitored Event Seeds. + DS + <ComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</ComputerName><RegistryAttributeDefinitions><RegistryAttributeDefinition><AttributeName>SeedExists</AttributeName><Path>SOFTWARE\CommunityMP\WinEvents</Path><PathType>0</PathType><AttributeType>0</AttributeType></RegistryAttributeDefinition></RegistryAttributeDefinitions><Frequency>3600</Frequency><ClassId>$MPElement[Name="Atea.Windows.Server.Monitoring.MonitoredEventSeed"]$</ClassId><InstanceSettings><Settings><Setting><Name>$MPElement[Name="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Name><Value>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Value></Setting><Setting><Name>$MPElement[Name="System!System.Entity"]/DisplayName$</Name><Value>WinEvents: $Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetbiosComputerName$</Value></Setting></Settings></InstanceSettings><Expression><SimpleExpression><ValueExpression><XPathQuery Type="String">Values/SeedExists</XPathQuery></ValueExpression><Operator>Equal</Operator><ValueExpression><Value Type="String">true</Value></ValueExpression></SimpleExpression></Expression> + Windows!Microsoft.Windows.FilteredRegistryDiscoveryProvider + Windows!Microsoft.Windows.OperatingSystem + true + true + Normal + false + Discovery + + + Atea.Windows.Server.Monitoring.MonitoredEventSeed + + + + + + + + \ No newline at end of file diff --git a/Atea.Windows.Server.Monitoring/HealthModel/Discoveries/Discoveries.mptg.mpx b/Atea.Windows.Server.Monitoring/HealthModel/Discoveries/Discoveries.mptg.mpx new file mode 100644 index 0000000..6c3342f Binary files /dev/null and b/Atea.Windows.Server.Monitoring/HealthModel/Discoveries/Discoveries.mptg.mpx differ diff --git a/Atea.Windows.Server.Monitoring/HealthModel/Monitors/AggregateMonitors.mptg b/Atea.Windows.Server.Monitoring/HealthModel/Monitors/AggregateMonitors.mptg new file mode 100644 index 0000000..9062467 --- /dev/null +++ b/Atea.Windows.Server.Monitoring/HealthModel/Monitors/AggregateMonitors.mptg @@ -0,0 +1,34 @@ + + + + + + WorstOf + 0 + + Atea.Windows.Server.Monitoring.EventMonitor + Ignore + Ignore + Atea.Windows.Server.Monitoring.ComputerHostsMonitoredEvent + Health!System.Health.AvailabilityState + Public + MonitoredEventRollup + Monitored Event Rollup + Health rollup from monitored event to computer. + Windows!Microsoft.Windows.Computer + false + AvailabilityHealth + true + Normal + true + None + Normal + MatchMonitorHealth + One or More Monitored Eventlog Error Events logged + This rollup monitor will alert if one or more Monitored Eventlog events have been triggered. + +Please refer to Health Explorer to see what specific events is the cause of this error. + + + + \ No newline at end of file diff --git a/Atea.Windows.Server.Monitoring/HealthModel/Monitors/AggregateMonitors.mptg.mpx b/Atea.Windows.Server.Monitoring/HealthModel/Monitors/AggregateMonitors.mptg.mpx new file mode 100644 index 0000000..1801e64 Binary files /dev/null and b/Atea.Windows.Server.Monitoring/HealthModel/Monitors/AggregateMonitors.mptg.mpx differ diff --git a/Atea.Windows.Server.Monitoring/HealthModel/Monitors/EventMonitoring.mptg b/Atea.Windows.Server.Monitoring/HealthModel/Monitors/EventMonitoring.mptg new file mode 100644 index 0000000..8ed318b --- /dev/null +++ b/Atea.Windows.Server.Monitoring/HealthModel/Monitors/EventMonitoring.mptg @@ -0,0 +1,52 @@ + + + + + Windows!Microsoft.Windows.2SingleEventLog2StateMonitorType + <FirstComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</FirstComputerName><FirstLogName>$Target/Property[Type="Atea.Windows.Server.Monitoring.MonitoredEvent"]/ErrorEventLog$</FirstLogName><FirstExpression><And><Expression><SimpleExpression><ValueExpression><XPathQuery Type="UnsignedInteger">EventDisplayNumber</XPathQuery></ValueExpression><Operator>Equal</Operator><ValueExpression><Value Type="UnsignedInteger">$Target/Property[Type="Atea.Windows.Server.Monitoring.MonitoredEvent"]/ErrorEventId$</Value></ValueExpression></SimpleExpression></Expression><Expression><SimpleExpression><ValueExpression><XPathQuery Type="Integer">EventLevel</XPathQuery></ValueExpression><Operator>Equal</Operator><ValueExpression><Value Type="Integer">$Target/Property[Type="Atea.Windows.Server.Monitoring.MonitoredEvent"]/ErrorEventLevel$</Value></ValueExpression></SimpleExpression></Expression><Expression><SimpleExpression><ValueExpression><XPathQuery Type="String">PublisherName</XPathQuery></ValueExpression><Operator>Equal</Operator><ValueExpression><Value Type="String">$Target/Property[Type="Atea.Windows.Server.Monitoring.MonitoredEvent"]/ErrorEventSource$</Value></ValueExpression></SimpleExpression></Expression></And></FirstExpression><SecondComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</SecondComputerName><SecondLogName>$Target/Property[Type="Atea.Windows.Server.Monitoring.MonitoredEvent"]/HealthyEventLog$</SecondLogName><SecondExpression><And><Expression><SimpleExpression><ValueExpression><XPathQuery Type="UnsignedInteger">EventDisplayNumber</XPathQuery></ValueExpression><Operator>Equal</Operator><ValueExpression><Value Type="UnsignedInteger">$Target/Property[Type="Atea.Windows.Server.Monitoring.MonitoredEvent"]/HealthyEventId$</Value></ValueExpression></SimpleExpression></Expression><Expression><SimpleExpression><ValueExpression><XPathQuery Type="Integer">EventLevel</XPathQuery></ValueExpression><Operator>Equal</Operator><ValueExpression><Value Type="Integer">$Target/Property[Type="Atea.Windows.Server.Monitoring.MonitoredEvent"]/HealthyEventLevel$</Value></ValueExpression></SimpleExpression></Expression><Expression><SimpleExpression><ValueExpression><XPathQuery Type="String">PublisherName</XPathQuery></ValueExpression><Operator>Equal</Operator><ValueExpression><Value Type="String">$Target/Property[Type="Atea.Windows.Server.Monitoring.MonitoredEvent"]/HealthyEventSource$</Value></ValueExpression></SimpleExpression></Expression></And></SecondExpression> + + + FirstEventRaised + ErrorEvent + FirstEventRaised + Error + + + SecondEventRaised + HealthyEvent + SecondEventRaised + Success + + + Health!System.Health.AvailabilityState + Internal + EventMonitor + Event Monitor + Monitors for events according to registry configuration of "MonitoredEvent". + Atea.Windows.Server.Monitoring.MonitoredEvent + true + AvailabilityHealth + true + Normal + true + Error + Normal + MatchMonitorHealth + Error Event Triggered! + $Target/Property[Type="Atea.Windows.Server.Monitoring.MonitoredEvent"]/EventMonitorName$: +$Target/Property[Type="Atea.Windows.Server.Monitoring.MonitoredEvent"]/ShortDescription$ + +Source: $Data/Context/EventSourceName$ +Event ID: $Data/Context/EventDisplayNumber$ +Event Category: $Data/Context/EventCategory$ +User: $Data/Context/UserName$ +Computer: $Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$ +Event Description: +$Data/Context/EventDescription$ + +At time $Data/Context/@time$ + false + + + + \ No newline at end of file diff --git a/Atea.Windows.Server.Monitoring/HealthModel/Monitors/EventMonitoring.mptg.mpx b/Atea.Windows.Server.Monitoring/HealthModel/Monitors/EventMonitoring.mptg.mpx new file mode 100644 index 0000000..4608caf Binary files /dev/null and b/Atea.Windows.Server.Monitoring/HealthModel/Monitors/EventMonitoring.mptg.mpx differ diff --git a/Atea.Windows.Server.Monitoring/HealthModel/Tasks/AddMonitoredEventTask.mpx b/Atea.Windows.Server.Monitoring/HealthModel/Tasks/AddMonitoredEventTask.mpx new file mode 100644 index 0000000..908cbfa --- /dev/null +++ b/Atea.Windows.Server.Monitoring/HealthModel/Tasks/AddMonitoredEventTask.mpx @@ -0,0 +1,32 @@ + + + + + Maintenance + + CHANGEME + 0 + 0 + CHANGEME + CHANGEME + 0 + 0 + CHANGEME + CHANGEME + CHANGEME + 300 + + + + + + + + + Add Monitored EventLog + Use this task to add a monitored eventlog event on this computer. Use overrides to set the friendly name, eventId, eventLevel et.c. + + + + + diff --git a/Atea.Windows.Server.Monitoring/Scripts/Add-MonitoredWindowsEventKey.ps1 b/Atea.Windows.Server.Monitoring/Scripts/Add-MonitoredWindowsEventKey.ps1 new file mode 100644 index 0000000..8b37dc3 --- /dev/null +++ b/Atea.Windows.Server.Monitoring/Scripts/Add-MonitoredWindowsEventKey.ps1 @@ -0,0 +1,33 @@ +param( + [Parameter(Mandatory = 'true')][string] $eventMonitorName, + [Parameter(Mandatory = 'true')][string] $shortDescription, + [Parameter(Mandatory = 'true')][int] $errorEventId, + [Parameter(Mandatory = 'true')][int] $errorEventLevel, + [Parameter(Mandatory = 'true')][string] $errorEventSource, + [Parameter(Mandatory = 'true')][string] $errorEventLog, + [Parameter(Mandatory = 'true')][int] $healthyEventId, + [Parameter(Mandatory = 'true')][int] $healthyEventLevel, + [Parameter(Mandatory = 'true')][string] $healthyEventSource, + [Parameter(Mandatory = 'true')][string] $healthyEventLog +) + +[string] $registryPath = "HKLM:\SOFTWARE\CommunityMP\WinEvents" +[string] $monitorRegistryPath = "$registryPath\$EventMonitorName" + +if (!(Test-Path $monitorRegistryPath)) { + Write-Output ("{0} does not exist, will create key." -f $monitorRegistryPath) + New-Item $monitorRegistryPath -Force + New-ItemProperty -Path $monitorRegistryPath -Name "ErrorEventId" -Value $errorEventId -PropertyType DWord -Force + New-ItemProperty -Path $monitorRegistryPath -Name "ErrorEventLevel" -Value $errorEventLevel -PropertyType DWord -Force + New-ItemProperty -Path $monitorRegistryPath -Name "ErrorEventSource" -Value $errorEventSource -PropertyType String -Force + New-ItemProperty -Path $monitorRegistryPath -Name "ErrorEventLog" -Value $errorEventLog -PropertyType String -Force + New-ItemProperty -Path $monitorRegistryPath -Name "HealthyEventId" -Value $healthyEventId -PropertyType DWord -Force + New-ItemProperty -Path $monitorRegistryPath -Name "HealthyEventLevel" -Value $healthyEventLevel -PropertyType DWord -Force + New-ItemProperty -Path $monitorRegistryPath -Name "HealthyEventSource" -Value $healthyEventSource -PropertyType String -Force + New-ItemProperty -Path $monitorRegistryPath -Name "HealthyEventLog" -Value $healthyEventLog -PropertyType String -Force + New-ItemProperty -Path $monitorRegistryPath -Name "EventShortDescription" -Value $shortDescription -PropertyType String -Force + + Write-Output "`nNew service key added`n`nPlease wait for next discovery, `nor restart the Microsoft Monitoring agent to force a discovery." +} else { + Write-Output "`nKey already exists!`n`nLeaving as is." +} diff --git a/Atea.Windows.Server.Monitoring/Scripts/Get-MonitoredEventDiscoveryDS.ps1 b/Atea.Windows.Server.Monitoring/Scripts/Get-MonitoredEventDiscoveryDS.ps1 new file mode 100644 index 0000000..f5c9def --- /dev/null +++ b/Atea.Windows.Server.Monitoring/Scripts/Get-MonitoredEventDiscoveryDS.ps1 @@ -0,0 +1,83 @@ +param($computerName) +### Gather vars and modules before script execution +$startVars = (Get-Variable -Scope Global).Name +$startModules = Get-Module +### + +[string] $registryPath = "HKLM:\SOFTWARE\CommunityMP\WinEvents" + +$knownDebugHosts = "Visual Studio Code Host","Windows PowerShell ISE Host" +$scriptHost = (Get-Host).Name +if ($scriptHost -in $knownDebugHosts) { + # script is running in a known debug environment, set debug values + $sourceId = '{172B8F37-C292-F5DF-B486-30CC30866928}' #dummy value for debugging + $targetId = '{5EEDD73A-F918-8A67-E63D-53C15FE4E4A3}' #dummy value for debugging + $isDebugging = $true +} +else { + $sourceId = '$MPElement$' + $targetId = '$Target/Id$' + $isDebugging = false +} + + +$omApi = New-Object -ComObject "MOM.ScriptAPI" +if ($isDebugging) { + if ((Get-WmiObject win32_computersystem).Domain -ne "WORKGROUP") { + $computerName = "$((Get-WmiObject win32_computersystem).DNSHostName).$((Get-WmiObject win32_computersystem).Domain)" + } + else { + $computerName = "$((Get-WmiObject win32_computersystem).DNSHostName)" + } +} + +[int] $eventCount = 0 +$discoData = $omApi.CreateDiscoveryData(0, $sourceId, $targetId) + +if (Test-Path -Path $registryPath) { + $subKeys = Get-ChildItem -Path $registryPath + foreach ($subKey in $subKeys) { + $discoInstance = $discoData.CreateClassInstance("$MPElement[Name='Atea.Windows.Server.Monitoring.MonitoredEvent']$") + $discoInstance.AddProperty("$MPElement[Name='Atea.Windows.Server.Monitoring.MonitoredEvent']/EventMonitorName$", $subKey.PSChildName) + $discoInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $subKey.PSChildName) + $discoInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $computerName) + foreach ($itemProperties in (Get-ItemProperty -Path $subKey.PSPath)) { + $discoInstance.AddProperty("$MPElement[Name='Atea.Windows.Server.Monitoring.MonitoredEvent']/ErrorEventId$", $itemProperties.ErrorEventId) + $discoInstance.AddProperty("$MPElement[Name='Atea.Windows.Server.Monitoring.MonitoredEvent']/ErrorEventLevel$", $itemProperties.ErrorEventLevel) + $discoInstance.AddProperty("$MPElement[Name='Atea.Windows.Server.Monitoring.MonitoredEvent']/ErrorEventLog$", $itemProperties.ErrorEventLog) + $discoInstance.AddProperty("$MPElement[Name='Atea.Windows.Server.Monitoring.MonitoredEvent']/ErrorEventSource$", $itemProperties.ErrorEventSource) + $discoInstance.AddProperty("$MPElement[Name='Atea.Windows.Server.Monitoring.MonitoredEvent']/HealthyEventId$", $itemProperties.HealthyEventId) + $discoInstance.AddProperty("$MPElement[Name='Atea.Windows.Server.Monitoring.MonitoredEvent']/HealthyEventLevel$", $itemProperties.HealthyEventLevel) + $discoInstance.AddProperty("$MPElement[Name='Atea.Windows.Server.Monitoring.MonitoredEvent']/HealthyEventLog$", $itemProperties.HealthyEventLog) + $discoInstance.AddProperty("$MPElement[Name='Atea.Windows.Server.Monitoring.MonitoredEvent']/HealthyEventSource$", $itemProperties.HealthyEventSource) + $discoInstance.AddProperty("$MPElement[Name='Atea.Windows.Server.Monitoring.MonitoredEvent']/ShortDescription$", $itemProperties.EventShortDescription) + } + $discoData.AddInstance($discoInstance) + $eventCount++ + } +} + +# Return discovery data to workflow... +if ($isDebugging) { + # or console/file, if we're debugging + $omAPI.AddItem($discoData) + $omAPI.ReturnItems() +} +else { + $discoData +} + +$omApi.LogScriptEvent("Get-MonitoredEventDiscoveryDS.ps1", 6110, 0, "Ran eventlog discovery, found $($eventCount) events to monitor.`n`nSourceId: $sourceId`nTargetId: $targetId`nPrincipalName: $computerName`nDebug: $isDebugging") + +### Unload generated vars and modules +foreach ($module in (Get-Module)) { + if ($module -notin $startModules) { + Remove-Module $module + } +} +foreach ($var in (Get-Variable -Scope Global).Name) { + if ($var -notin $startVars) { + Remove-Variable $var -ErrorAction SilentlyContinue + } +} +### diff --git a/Atea.Windows.Server.Monitoring/ServiceModel/Classes/MonitoredEvent.mpx b/Atea.Windows.Server.Monitoring/ServiceModel/Classes/MonitoredEvent.mpx new file mode 100644 index 0000000..43ae633 --- /dev/null +++ b/Atea.Windows.Server.Monitoring/ServiceModel/Classes/MonitoredEvent.mpx @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + Monitored Event Class + This class represents monitored Windows Eventlog Events defined in Registry for self-service and automation. + + + Event Monitor-Name + Registry-key name, and displayname, of the defined monitored event. + + + ErrorEventId + EventId of event that trips a fault state + + + Error Event Level + + + + ErrorEventSource + Event Source of event that trips a fault state + + + ErrorEventLog + Event Logname of event that trips a fault state + + + HealthyEventId + EventId of event that trips an OK state + + + Healthy Event Level + + + + + + HealthyEventSource + Event Source of event that trips an OK state + + + HealthyEventLog + Event Logname of event that trips an OK state + + + ShortDescription + Short description of events, will be included in alert. + + + + + diff --git a/Atea.Windows.Server.Monitoring/ServiceModel/Classes/MonitoredEventSeed.mpx b/Atea.Windows.Server.Monitoring/ServiceModel/Classes/MonitoredEventSeed.mpx new file mode 100644 index 0000000..4dd2fbd --- /dev/null +++ b/Atea.Windows.Server.Monitoring/ServiceModel/Classes/MonitoredEventSeed.mpx @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + Monitored Event Seed-Class + Used to pre-stage the powershell script-based discovery of registry-configured monitored events. + + + + + diff --git a/Atea.Windows.Server.Monitoring/ServiceModel/RelationShips/ComputerHostsMonitoredEvent.mpx b/Atea.Windows.Server.Monitoring/ServiceModel/RelationShips/ComputerHostsMonitoredEvent.mpx new file mode 100644 index 0000000..87f3e05 --- /dev/null +++ b/Atea.Windows.Server.Monitoring/ServiceModel/RelationShips/ComputerHostsMonitoredEvent.mpx @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + Atea Windows Computer Hosts Monitored Event Relationship + + + + + + diff --git a/Atea.Windows.Server.Monitoring/TypeLibrary/ModuleTypes/ProbeActions/AddMonitoredEventTaskPSProbe.mpx b/Atea.Windows.Server.Monitoring/TypeLibrary/ModuleTypes/ProbeActions/AddMonitoredEventTaskPSProbe.mpx new file mode 100644 index 0000000..22fa76a --- /dev/null +++ b/Atea.Windows.Server.Monitoring/TypeLibrary/ModuleTypes/ProbeActions/AddMonitoredEventTaskPSProbe.mpx @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Add-MonitoredWindowsEventKey.ps1 + $IncludeFileContent/Scripts/Add-MonitoredWindowsEventKey.ps1$ + + + + eventMonitorName + $Config/EventMonitorName$ + + + errorEventId + $Config/ErrorEventId$ + + + errorEventLevel + $Config/ErrorEventLevel$ + + + errorEventSource + $Config/ErrorEventSource$ + + + errorEventLog + $Config/ErrorEventLog$ + + + healthyEventId + $Config/HealthyEventId$ + + + healthyEventLevel + $Config/HealthyEventLevel$ + + + healthyEventSource + $Config/HealthyEventSource$ + + + healthyEventLog + $Config/HealthyEventLog$ + + + shortDescription + $Config/ShortDescription$ + + + $Config/TimeoutSeconds$ + true + + + + + + + + Windows!Microsoft.Windows.SerializedObjectData + System!System.BaseData + + + + \ No newline at end of file diff --git a/Atea.Windows.Service.Monitoring/Atea.Windows.Service.Monitoring.mpproj b/Atea.Windows.Service.Monitoring/Atea.Windows.Service.Monitoring.mpproj index 9c8b433..cc5618b 100644 --- a/Atea.Windows.Service.Monitoring/Atea.Windows.Service.Monitoring.mpproj +++ b/Atea.Windows.Service.Monitoring/Atea.Windows.Service.Monitoring.mpproj @@ -1,12 +1,12 @@  - + Debug {53470240-d3b9-4ef1-b4e1-6a075fb07593} Atea.Windows.Service Atea.Windows.Service.Monitoring Atea.Windows.Service.Monitoring - 1.0.3.0 + 1.0.3.230 v7.0 OM 1.1.0.0 @@ -181,5 +181,8 @@ + + + \ No newline at end of file diff --git a/Atea.Windows.Service.Monitoring/HealthModel/Discoveries/ServiceDiscovery.mpx b/Atea.Windows.Service.Monitoring/HealthModel/Discoveries/ServiceDiscovery.mpx index 845bb5f..67da2be 100644 --- a/Atea.Windows.Service.Monitoring/HealthModel/Discoveries/ServiceDiscovery.mpx +++ b/Atea.Windows.Service.Monitoring/HealthModel/Discoveries/ServiceDiscovery.mpx @@ -5,6 +5,7 @@ Discovery + @@ -16,10 +17,15 @@ $Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$ 300 AteaWinSvcServiceDiscoveryDS.vbs + false false $MPElement[Name="Atea.Windows.Service.Service"]$ + + $MPElement[Name='System!System.Entity']/DisplayName$ + $Data/Property[@Name='EntityDisplayName']$ + $MPElement[Name='MSNL!Microsoft.SystemCenter.NTService']/ServiceName$ $Data/Property[@Name='Name']$ diff --git a/Atea.Windows.Service.Monitoring/HealthModel/Rules/AlertRules.mptg b/Atea.Windows.Service.Monitoring/HealthModel/Rules/AlertRules.mptg index b04d58c..d65db84 100644 --- a/Atea.Windows.Service.Monitoring/HealthModel/Rules/AlertRules.mptg +++ b/Atea.Windows.Service.Monitoring/HealthModel/Rules/AlertRules.mptg @@ -23,7 +23,7 @@ Normal Error Failed to Recovery Service - $Data/Property[@Name='EventDescription']$ + $Data/EventDescription$ diff --git a/Atea.Windows.Service.Monitoring/HealthModel/Rules/AlertRules.mptg.mpx b/Atea.Windows.Service.Monitoring/HealthModel/Rules/AlertRules.mptg.mpx index 68aefee..a2f6803 100644 Binary files a/Atea.Windows.Service.Monitoring/HealthModel/Rules/AlertRules.mptg.mpx and b/Atea.Windows.Service.Monitoring/HealthModel/Rules/AlertRules.mptg.mpx differ diff --git a/Atea.Windows.Service.Monitoring/HealthModel/Tasks/Recoveries/ServiceStartRecoveryTask.mpx b/Atea.Windows.Service.Monitoring/HealthModel/Tasks/Recoveries/ServiceStartRecoveryTask.mpx index 0e1d00c..6dc5b00 100644 --- a/Atea.Windows.Service.Monitoring/HealthModel/Tasks/Recoveries/ServiceStartRecoveryTask.mpx +++ b/Atea.Windows.Service.Monitoring/HealthModel/Tasks/Recoveries/ServiceStartRecoveryTask.mpx @@ -6,7 +6,7 @@ - start $Target/Property[Type='MSNL!Microsoft.SystemCenter.NTService']/ServiceName$ + start "$Target/Property[Type='MSNL!Microsoft.SystemCenter.NTService']/ServiceName$" 300 true diff --git a/Atea.Windows.Service.Monitoring/Scripts/AteaAutoSvcPBScript.vbs b/Atea.Windows.Service.Monitoring/Scripts/AteaAutoSvcPBScript.vbs index 2f54d36..c04c533 100644 --- a/Atea.Windows.Service.Monitoring/Scripts/AteaAutoSvcPBScript.vbs +++ b/Atea.Windows.Service.Monitoring/Scripts/AteaAutoSvcPBScript.vbs @@ -39,62 +39,66 @@ If NOT IsNull(automaticServices) Then ' We got a "hit" on a service name configured in the registry ' Create the SCOM property bag instances and return them to SCOM Set scomApi = CreateObject("MOM.ScriptAPI") - + For Each automaticService In automaticServices serviceName = automaticService.Name ' Add one property bag per service LogEvent SCOM_DEBUG,SCOM_INFO,"Found automatic service: " & serviceName - If Ubound(Filter(serviceExceptions, serviceName,True,1)) > -1 Then - 'Got match, service shound be excluded from discovery - LogEvent SCOM_DEBUG,SCOM_INFO,"Service is ignored due to exclusion list: " & serviceName - ElseIf Ubound(Filter(standardExclusions, serviceName,True,1)) > -1 Then - 'Got match, service shound be excluded from discovery - LogEvent SCOM_DEBUG,SCOM_INFO,"Service is ignored due to standard exclusion list: " & serviceName - ElseIf Ubound(Filter(xylemExclusions, serviceName,True,1)) > -1 Then - 'Got match, service shound be excluded from discovery - LogEvent SCOM_DEBUG,SCOM_INFO,"Service is ignored due to Xylem exclusion list: " & serviceName - Else - ' No match, service is not in exclusion list. - ' Process and add to property bag - If Err.Number = 0 Then - With automaticService - Set scomPropertyBag = scomApi.CreatePropertyBag() ' Instance of a new property bag - - ' Start adding values to the propertybag - Call scomPropertyBag.AddValue("Name",Cstr(.Name)) - Call scomPropertyBag.AddValue("DisplayName",Cstr(.DisplayName)) - If .Description <> vbNull Then - Call scomPropertyBag.AddValue("Description",Cstr(.Description)) + If Ubound(Filter(serviceExceptions, serviceName,True,1)) > -1 Then + 'Got match, service shound be excluded from discovery + LogEvent SCOM_DEBUG,SCOM_INFO,"Service is ignored due to exclusion list: " & serviceName + ElseIf Ubound(Filter(standardExclusions, serviceName,True,1)) > -1 Then + 'Got match, service shound be excluded from discovery + LogEvent SCOM_DEBUG,SCOM_INFO,"Service is ignored due to standard exclusion list: " & serviceName + ElseIf Ubound(Filter(xylemExclusions, serviceName,True,1)) > -1 Then + 'Got match, service shound be excluded from discovery + LogEvent SCOM_DEBUG,SCOM_INFO,"Service is ignored due to Xylem exclusion list: " & serviceName + Else + ' No match, service is not in exclusion list. + ' Process and add to property bag + If Err.Number = 0 Then + With automaticService + Set scomPropertyBag = scomApi.CreatePropertyBag() ' Instance of a new property bag + + ' Start adding values to the propertybag + Call scomPropertyBag.AddValue("Name",Cstr(.Name)) + Call scomPropertyBag.AddValue("DisplayName",Cstr(.DisplayName)) + If .Description <> vbNull Then + Call scomPropertyBag.AddValue("Description",Cstr(.Description)) + Else + Call scomPropertyBag.AddValue("Description","") + End If + Call scomPropertyBag.AddValue("SystemName",Cstr(.SystemName)) + Call scomPropertyBag.AddValue("PathName",Cstr(.PathName)) + Call scomPropertyBag.AddValue("ProcessID",Cstr(.ProcessID)) + If .StartName <> vbNull Then + Call scomPropertyBag.AddValue("ServiceUser",Cstr(.StartName)) Else - Call scomPropertyBag.AddValue("Description","") + Call scomPropertyBag.AddValue("ServiceUser","") End If - Call scomPropertyBag.AddValue("SystemName",Cstr(.SystemName)) - Call scomPropertyBag.AddValue("PathName",Cstr(.PathName)) - Call scomPropertyBag.AddValue("ProcessID",Cstr(.ProcessID)) - Call scomPropertyBag.AddValue("ServiceUser",Cstr(.StartName)) - Call scomPropertyBag.AddValue("State",Cstr(.State)) - Call scomPropertyBag.AddValue("Status",Cstr(.Status)) - Call scomPropertyBag.AddValue("StartMode",Cstr(.StartMode)) - Call scomPropertyBag.AddValue("ServiceType",Cstr(.ServiceType)) - Call scomPropertyBag.AddValue("TagID",Cstr(.TagID)) - - Call scomApi.AddItem(scomPropertyBag) ' Add the property bag to the collection - End With - Else - Select Case returnValue - Case 242100 - LogEvent SCOM_SCRIPT_WARNING, SCOM_WARNING, "Could not properly connect to the service repository on " & computerName & ", check RunAs user rights." - Case 242101 - LogEvent SCOM_SCRIPT_WARNING, SCOM_WARNING, "Could not match registry value """ & serviceName & """to an existing service." - Case 424 - LogEvent SCOM_SCRIPT_WARNING, SCOM_WARNING, "Connection to WMI-service on " & computerName & " failed. Check network connections and RunAs user rights." - Case Else - LogEvent SCOM_SCRIPT_WARNING, SCOM_WARNING, "An unhandled script event occured, please contact your SCOM admins." & vbCrLf & "Err.number = " & Err.Number - End Select - End If 'End error check - End If 'End exclusion check - + Call scomPropertyBag.AddValue("State",Cstr(.State)) + Call scomPropertyBag.AddValue("Status",Cstr(.Status)) + Call scomPropertyBag.AddValue("StartMode",Cstr(.StartMode)) + Call scomPropertyBag.AddValue("ServiceType",Cstr(.ServiceType)) + Call scomPropertyBag.AddValue("TagID",Cstr(.TagID)) + + Call scomApi.AddItem(scomPropertyBag) ' Add the property bag to the collection + End With + Else + Select Case returnValue + Case 242100 + LogEvent SCOM_SCRIPT_WARNING, SCOM_WARNING, "Could not properly connect to the service repository on " & computerName & ", check RunAs user rights." + Case 242101 + LogEvent SCOM_SCRIPT_WARNING, SCOM_WARNING, "Could not match registry value """ & serviceName & """to an existing service." + Case 424 + LogEvent SCOM_SCRIPT_WARNING, SCOM_WARNING, "Connection to WMI-service on " & computerName & " failed. Check network connections and RunAs user rights." + Case Else + LogEvent SCOM_SCRIPT_WARNING, SCOM_WARNING, "An unhandled script event occured, please contact your SCOM admins." & vbCrLf & "Err.number = " & Err.Number + End Select + End If 'End error check + End If 'End exclusion check + Set serviceObject = Nothing Next Call scomApi.ReturnItems() ' Return the property bag collection to SCOM @@ -131,7 +135,7 @@ Sub CheckParameters(numRequiredParams) ''' Dim scriptArguments Set scriptArguments = WScript.Arguments - + If IsNumeric(numRequiredParams) Then If scriptArguments.Count >= numRequiredParams Then Set scriptParameters = scriptArguments @@ -153,7 +157,7 @@ Sub LogEvent(logEventID, logSeverity, logMessage) ''' Dim scomApi, scriptName scriptName = WScript.ScriptName - + If logEventID <> SCOM_DEBUG Then Set scomApi = CreateObject("MOM.ScriptAPI") Call scomApi.LogScriptEvent(scriptName,logEventID,logSeverity,logMessage) diff --git a/Atea.Windows.Service.Monitoring/Scripts/AteaWinSvcServiceDiscoveryDS.vbs b/Atea.Windows.Service.Monitoring/Scripts/AteaWinSvcServiceDiscoveryDS.vbs index 58927c7..3a878b5 100644 --- a/Atea.Windows.Service.Monitoring/Scripts/AteaWinSvcServiceDiscoveryDS.vbs +++ b/Atea.Windows.Service.Monitoring/Scripts/AteaWinSvcServiceDiscoveryDS.vbs @@ -1,6 +1,6 @@ Option Explicit -Dim computerName, keyPath, registryObject, registryValues, serviceName, debugEnabled, scriptParameters, serviceClass +Dim computerName, keyPath, registryObject, registryValues, serviceName, useServiceDisplayName, debugEnabled, scriptParameters, serviceClass Dim scomApi, scomPropertyBag, serviceObject, returnValue ''' @@ -22,9 +22,10 @@ CONST SCOM_SCRIPT_ERROR = 19202 CONST SCOM_DEBUG = 19999 -CheckParameters 2 +CheckParameters 3 computerName = CStr(scriptParameters(0)) -debugEnabled = CBool(scriptParameters(1)) +useServiceDisplayName = CBool(scriptParameters(1)) +debugEnabled = CBool(scriptParameters(2)) Set registryObject = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & computerName & "\root\default:StdRegProv") keyPath = "Software\Atea\WinSvc" ' ToDo: Make this a parameter @@ -35,7 +36,7 @@ If NOT IsNull(registryValues) Then ' We got a "hit" on a service name configured in the registry ' Create the SCOM property bag instances and return them to SCOM Set scomApi = CreateObject("MOM.ScriptAPI") - + For Each serviceName in registryValues ' Add one property bag per service LogEvent SCOM_DEBUG,SCOM_INFO,"Found value: HKLM\" & keyPath & "\" & serviceName @@ -59,7 +60,13 @@ If NOT IsNull(registryValues) Then Call scomPropertyBag.AddValue("StartMode",.StartMode) Call scomPropertyBag.AddValue("ServiceType",.ServiceType) Call scomPropertyBag.AddValue("TagID",.TagID) - Call scomPropertyBag.AddValue("keyPath",keyPath) + Call scomPropertyBag.AddValue("keyPath",keyPath) + + If useServiceDisplayName Then + Call scomPropertyBag.AddValue("EntityDisplayName",.DisplayName) + Else + Call scomPropertyBag.AddValue("EntityDisplayName",.Name) + End If Call scomApi.AddItem(scomPropertyBag) ' Add the property bag to the collection End With @@ -75,7 +82,7 @@ If NOT IsNull(registryValues) Then LogEvent SCOM_SCRIPT_WARNING, SCOM_WARNING, "An unhandled script event occured, please contact your SCOM admins." & vbCrLf & "Err.number = " & returnValue End Select End If - + Set serviceObject = Nothing Next Call scomApi.ReturnItems() ' Return the property bag collection to SCOM @@ -86,26 +93,26 @@ If NOT IsNull(registryValues) Then "Error code: " & Err.Num & vbCrLf & _ "Error Description: " & Err.Description - ' Issue #4 - ' Discovery never removing services efter the only remaining string value is deleted. - ' Needs to return an empty property bag. - Set scomApi = CreateObject("MOM.ScriptingAPI") - Set scomPropertyBag = scomApi.CreatePropertyBag() - Call scomApi.Return(scomPropertyBag) - Set scomApi = Nothing + ' Issue #4 + ' Discovery never removing services efter the only remaining string value is deleted. + ' Needs to return an empty property bag. + Set scomApi = CreateObject("MOM.ScriptingAPI") + Set scomPropertyBag = scomApi.CreatePropertyBag() + Call scomApi.Return(scomPropertyBag) + Set scomApi = Nothing End If Else ' Could not read from registry, perhaps key is missing? LogEvent SCOM_DEBUG,SCOM_INFO,"Failed to read from: HKLM\" & keyPath & "\" - ' Issue #4 - ' Discovery never removing services efter the only remaining string value is deleted. - ' Needs to return an empty property bag. - Set scomApi = CreateObject("MOM.ScriptAPI") - Set scomApi = CreateObject("MOM.ScriptingAPI") - Set scomPropertyBag = scomApi.CreatePropertyBag() - Call scomApi.Return(scomPropertyBag) - Set scomApi = Nothing + ' Issue #4 + ' Discovery never removing services efter the only remaining string value is deleted. + ' Needs to return an empty property bag. + Set scomApi = CreateObject("MOM.ScriptAPI") + Set scomApi = CreateObject("MOM.ScriptingAPI") + Set scomPropertyBag = scomApi.CreatePropertyBag() + Call scomApi.Return(scomPropertyBag) + Set scomApi = Nothing End If @@ -129,7 +136,7 @@ Sub CheckParameters(numRequiredParams) ''' Dim scriptArguments Set scriptArguments = WScript.Arguments - + If IsNumeric(numRequiredParams) Then If scriptArguments.Count >= numRequiredParams Then Set scriptParameters = scriptArguments @@ -151,7 +158,7 @@ Sub LogEvent(logEventID, logSeverity, logMessage) ''' Dim scomApi, scriptName scriptName = WScript.ScriptName - + If logEventID <> SCOM_DEBUG Then Set scomApi = CreateObject("MOM.ScriptAPI") Call scomApi.LogScriptEvent(scriptName,logEventID,logSeverity,logMessage) @@ -176,11 +183,11 @@ Class Service Public Status Public StartMode Public ServiceType - Public ProcessID + Public ProcessID Public TagID - - + + Private Sub Class_Initialize() Name = "" DisplayName = "" @@ -192,7 +199,7 @@ Class Service Public Function GetServiceInfo(mServiceName, mComputerName) Dim wmi, wmiServices, wmiService, serviceClass, returnCode - + returnCode = 0 ' 0 = no error On Error Resume Next Set wmi = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & mComputerName & "\root\cimv2") @@ -202,19 +209,19 @@ Class Service For Each wmiService In wmiServices If LCase(wmiService.Name) = LCase(mServiceName) Then Name = ClearIllegalReturnValues(wmiService.Name) - DisplayName = ClearIllegalReturnValues(wmiService.Caption) - Description = ClearIllegalReturnValues(wmiService.Description) - ServiceUser = ClearIllegalReturnValues(wmiService.StartName) - SystemName = ClearIllegalReturnValues(wmiService.SystemName) - PathName = ClearIllegalReturnValues(wmiService.PathName) - State = ClearIllegalReturnValues(wmiService.State) - Status = ClearIllegalReturnValues(wmiService.Status) - StartMode = ClearIllegalReturnValues(wmiService.StartMode) - ServiceType = ClearIllegalReturnValues(wmiService.ServiceType) - ProcessID = ClearIllegalReturnValues(wmiService.ProcessID) - TagID = ClearIllegalReturnValues(wmiService.TagID) - Else - returnCode = 242101 + DisplayName = ClearIllegalReturnValues(wmiService.Caption) + Description = ClearIllegalReturnValues(wmiService.Description) + ServiceUser = ClearIllegalReturnValues(wmiService.StartName) + SystemName = ClearIllegalReturnValues(wmiService.SystemName) + PathName = ClearIllegalReturnValues(wmiService.PathName) + State = ClearIllegalReturnValues(wmiService.State) + Status = ClearIllegalReturnValues(wmiService.Status) + StartMode = ClearIllegalReturnValues(wmiService.StartMode) + ServiceType = ClearIllegalReturnValues(wmiService.ServiceType) + ProcessID = ClearIllegalReturnValues(wmiService.ProcessID) + TagID = ClearIllegalReturnValues(wmiService.TagID) + Else + returnCode = 242101 End If Next Else @@ -230,12 +237,12 @@ Class Service Set wmiServices = Nothing Set wmi = Nothing End Function - + Private Function ClearIllegalReturnValues(StringToClear) - ' Check for NULL - If IsNull(StringToClear) Then - StringToClear = "" - End If - ClearIllegalReturnValues = StringToClear + ' Check for NULL + If IsNull(StringToClear) Then + StringToClear = "" + End If + ClearIllegalReturnValues = StringToClear End Function End Class \ No newline at end of file diff --git a/Atea.Windows.Service.Monitoring/Scripts/Get-RunningServices.ps1 b/Atea.Windows.Service.Monitoring/Scripts/Get-RunningServices.ps1 index 8cb1f0b..7f49c7b 100644 --- a/Atea.Windows.Service.Monitoring/Scripts/Get-RunningServices.ps1 +++ b/Atea.Windows.Service.Monitoring/Scripts/Get-RunningServices.ps1 @@ -1 +1 @@ -gwmi -query "select * from Win32_Service where State='Running'" | ft Name,DisplayName -AutoSize +Get-WMIObject -query "select * from Win32_Service where State='Running'" | Format-Table Name,DisplayName -AutoSize diff --git a/Atea.Windows.Service.Monitoring/TypeLibrary/ModuleTypes/DataSources/ServiceDiscoveryDS.mpx b/Atea.Windows.Service.Monitoring/TypeLibrary/ModuleTypes/DataSources/ServiceDiscoveryDS.mpx index 9b806e4..9992436 100644 --- a/Atea.Windows.Service.Monitoring/TypeLibrary/ModuleTypes/DataSources/ServiceDiscoveryDS.mpx +++ b/Atea.Windows.Service.Monitoring/TypeLibrary/ModuleTypes/DataSources/ServiceDiscoveryDS.mpx @@ -10,12 +10,14 @@ + + @@ -34,6 +36,7 @@ $Config/ScriptName$ $Config/ComputerName$ + $Config/UseServiceDisplayName$ $Config/Debug$ $Config/TimeoutSeconds$ @@ -71,6 +74,10 @@ Timeout Seconds + + Use Service Display Name + Use service display name instead of service name as display name of discovered services. + diff --git a/Atea.Windows.Service.Monitoring/TypeLibrary/ModuleTypes/ProbeActions/AutoServiceDiscoveryVBSProbe.mpx b/Atea.Windows.Service.Monitoring/TypeLibrary/ModuleTypes/ProbeActions/AutoServiceDiscoveryVBSProbe.mpx index e03be12..f190398 100644 --- a/Atea.Windows.Service.Monitoring/TypeLibrary/ModuleTypes/ProbeActions/AutoServiceDiscoveryVBSProbe.mpx +++ b/Atea.Windows.Service.Monitoring/TypeLibrary/ModuleTypes/ProbeActions/AutoServiceDiscoveryVBSProbe.mpx @@ -13,7 +13,7 @@ AteaAutoSvcPBScript.vbs - $Config/ComputerName$ $Config/Debug$ $Config/ServiceExceptions$ + $Config/ComputerName$ $Config/Debug$ "$Config/ServiceExceptions$" $IncludeFileContent/Scripts/AteaAutoSvcPBScript.vbs$ $Config/TimeoutSeconds$ diff --git a/Atea.Windows.Service.Monitoring/TypeLibrary/ModuleTypes/ProbeActions/SelectedServiceVBSProbe.mpx b/Atea.Windows.Service.Monitoring/TypeLibrary/ModuleTypes/ProbeActions/SelectedServiceVBSProbe.mpx index dfe5410..5d2adf3 100644 --- a/Atea.Windows.Service.Monitoring/TypeLibrary/ModuleTypes/ProbeActions/SelectedServiceVBSProbe.mpx +++ b/Atea.Windows.Service.Monitoring/TypeLibrary/ModuleTypes/ProbeActions/SelectedServiceVBSProbe.mpx @@ -5,6 +5,7 @@ + @@ -13,7 +14,7 @@ $Config/ScriptName$ - $Config/ComputerName$ $Config/Debug$ + $Config/ComputerName$ $Config/UseServiceDisplayName$ $Config/Debug$ $IncludeFileContent/Scripts/AteaWinSvcServiceDiscoveryDS.vbs$ $Config/TimeoutSeconds$ diff --git a/Atea.Windows.sln b/Atea.Windows.sln index 70827ec..0b8cb48 100644 --- a/Atea.Windows.sln +++ b/Atea.Windows.sln @@ -22,31 +22,36 @@ Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "Atea.Windows.Installer", "A {361E64DE-7730-493D-8464-C22911EB5791} = {361E64DE-7730-493D-8464-C22911EB5791} EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{672DDC40-3495-4570-8F1E-039E77A6AC88}" + ProjectSection(SolutionItems) = preProject + CHANGELOG.md = CHANGELOG.md + README.md = README.md + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x86 = Debug|x86 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {361E64DE-7730-493D-8464-C22911EB5791}.Debug|x86.ActiveCfg = Debug|x86 - {361E64DE-7730-493D-8464-C22911EB5791}.Debug|x86.Build.0 = Debug|x86 + {361E64DE-7730-493D-8464-C22911EB5791}.Debug|x86.ActiveCfg = Release|x86 + {361E64DE-7730-493D-8464-C22911EB5791}.Debug|x86.Build.0 = Release|x86 {361E64DE-7730-493D-8464-C22911EB5791}.Release|x86.ActiveCfg = Release|x86 {361E64DE-7730-493D-8464-C22911EB5791}.Release|x86.Build.0 = Release|x86 - {E346D1C7-2CA1-4E15-A871-663F747FBFDE}.Debug|x86.ActiveCfg = Debug|x86 - {E346D1C7-2CA1-4E15-A871-663F747FBFDE}.Debug|x86.Build.0 = Debug|x86 + {E346D1C7-2CA1-4E15-A871-663F747FBFDE}.Debug|x86.ActiveCfg = Release|x86 + {E346D1C7-2CA1-4E15-A871-663F747FBFDE}.Debug|x86.Build.0 = Release|x86 {E346D1C7-2CA1-4E15-A871-663F747FBFDE}.Release|x86.ActiveCfg = Release|x86 {E346D1C7-2CA1-4E15-A871-663F747FBFDE}.Release|x86.Build.0 = Release|x86 - {53470240-D3B9-4EF1-B4E1-6A075FB07593}.Debug|x86.ActiveCfg = Debug|x86 - {53470240-D3B9-4EF1-B4E1-6A075FB07593}.Debug|x86.Build.0 = Debug|x86 + {53470240-D3B9-4EF1-B4E1-6A075FB07593}.Debug|x86.ActiveCfg = Release|x86 + {53470240-D3B9-4EF1-B4E1-6A075FB07593}.Debug|x86.Build.0 = Release|x86 {53470240-D3B9-4EF1-B4E1-6A075FB07593}.Release|x86.ActiveCfg = Release|x86 {53470240-D3B9-4EF1-B4E1-6A075FB07593}.Release|x86.Build.0 = Release|x86 - {C55B880E-F609-462C-AED3-67F44531D4D7}.Debug|x86.ActiveCfg = Debug|x86 - {C55B880E-F609-462C-AED3-67F44531D4D7}.Debug|x86.Build.0 = Debug|x86 + {C55B880E-F609-462C-AED3-67F44531D4D7}.Debug|x86.ActiveCfg = Release|x86 + {C55B880E-F609-462C-AED3-67F44531D4D7}.Debug|x86.Build.0 = Release|x86 {C55B880E-F609-462C-AED3-67F44531D4D7}.Release|x86.ActiveCfg = Release|x86 {C55B880E-F609-462C-AED3-67F44531D4D7}.Release|x86.Build.0 = Release|x86 - {1783668C-8085-419E-B862-D3CFEE8401AC}.Debug|x86.ActiveCfg = Debug + {1783668C-8085-419E-B862-D3CFEE8401AC}.Debug|x86.ActiveCfg = Release {1783668C-8085-419E-B862-D3CFEE8401AC}.Release|x86.ActiveCfg = Release - {1783668C-8085-419E-B862-D3CFEE8401AC}.Release|x86.Build.0 = Release EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/CHANGELOG.md b/CHANGELOG.md index e6b3b5a..cbc5e2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,30 +1,44 @@ # Change Log + All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] + ### Added + - Atea.Windows.Installer project Added - Release folder created - Automatic builds and MSI-packaging to /Release folder - Powershell based installation/update scripts - This changelog! +- File Age Monitor +- MonitoredEvent class, task and discovery ### Changed + - Updated documentation design +- Install Script no longer uses the MSI-file, works directly with mp-files ### Fixed + - [Svc Recovery alert has wrong eventlog name #6](https://github.com/stegenfeldt/Atea.Windows/issues/6) - Reconfigured Auto Deploy after extension update - Adv Service Recovery logging to task output +- Exclusions on AutoService discovery +- Standard Service Restart recovery task now supports services with spaces +- Service displaystring discovery ### Removed + - Old Downloads folder ## [1.0.2] - 2016-10-25 + ### Added + - Atea.Windows.File.Monitoring MP from Atea.FileCreationTime, refactored for VSAE - Documentation available at [https://stegenfeldt.github.io/Atea.Windows](https://stegenfeldt.github.io/Atea.Windows) - List Running Services tasks @@ -34,21 +48,25 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Advanced Service Restart tasks ### Changed + - Bunch of spellchecks ### Fixed + - "undiscovery" of services when last service is gone ## [1.0.1] - 2016-01-12 + ### Added + - New class for Powershell enabled windows servers - Discovery of "Automatic" services, disabled by default - Service exclusion support in Automatic discovery - Recovery Monitor on monitored services for automatic restart - DiskUsedGB performance collection rule - ### Changed + - Converted Atea.WinSvc to VSAE project in Atea.Windows solution - Refactored Atea.WinSvc to Atea.Windows.Service - Updated discovery scripts to Powershell diff --git a/README.md b/README.md index 18df454..347afdb 100644 --- a/README.md +++ b/README.md @@ -2,22 +2,33 @@ The Atea.Windows MP collection is a number of, somewhat related, management packs developed by Atea Sverige AB for our customers. +[![Build Status](https://stegenfeldt.visualstudio.com/SCOM%20MP%20-%20Atea.Windows/_apis/build/status/stegenfeldt.Atea.Windows)](https://stegenfeldt.visualstudio.com/SCOM%20MP%20-%20Atea.Windows/_build/latest?definitionId=1) + +## Tools needed + +This project is built using Visual Studio 2017 (Community). +In addition to that, you'd need the following extensions: + +- VSAE - Visual Studio Authoring Extensions +- Auto Deploy - +- Microsoft Visual Studio 2017/2015 Installer Projects + ## Customers/Sponsors The following customers have graciously allowed us to co-develop this MP and share our work with our other customers and the rest of the world. -* Clas Ohlson -* Spendrups -* ABB -* Borlänge Kommun -* Piteå Kommun -* Atea Integration Services -* Landstinget Gävleborg -* SSAB -* Xylem Water Solutions +- Clas Ohlson +- Spendrups +- ABB +- Borlänge Kommun +- Piteå Kommun +- Atea Integration Services +- Region Gävleborg +- SSAB +- Xylem Water Solutions ## Disclaimer -While most of this is developed from scratch, some inspiration has been taken from other community members. +While most of this is developed from scratch, some inspiration has been taken from other community members. In such case, we have tried to include links in the comments. If you think we have missed something, please let me know and we will add the proper credits. diff --git a/Released/Atea.Windows.File.Monitoring.mp b/Released/Atea.Windows.File.Monitoring.mp index 8039c9b..817e1f3 100644 Binary files a/Released/Atea.Windows.File.Monitoring.mp and b/Released/Atea.Windows.File.Monitoring.mp differ diff --git a/Released/Atea.Windows.Installer.msi b/Released/Atea.Windows.Installer.msi index f0deaa8..d807fec 100644 Binary files a/Released/Atea.Windows.Installer.msi and b/Released/Atea.Windows.Installer.msi differ diff --git a/Released/Atea.Windows.Library.mp b/Released/Atea.Windows.Library.mp index b5ca56d..367823d 100644 Binary files a/Released/Atea.Windows.Library.mp and b/Released/Atea.Windows.Library.mp differ diff --git a/Released/Atea.Windows.Library.mpb b/Released/Atea.Windows.Library.mpb new file mode 100644 index 0000000..0f1effa Binary files /dev/null and b/Released/Atea.Windows.Library.mpb differ diff --git a/Released/Atea.Windows.Server.Monitoring.mp b/Released/Atea.Windows.Server.Monitoring.mp index 81312f0..9a41052 100644 Binary files a/Released/Atea.Windows.Server.Monitoring.mp and b/Released/Atea.Windows.Server.Monitoring.mp differ diff --git a/Released/Atea.Windows.Service.Monitoring.mp b/Released/Atea.Windows.Service.Monitoring.mp index 852b0eb..5bdac5d 100644 Binary files a/Released/Atea.Windows.Service.Monitoring.mp and b/Released/Atea.Windows.Service.Monitoring.mp differ diff --git a/Released/Install-AteaWindowsMP.ps1 b/Released/Install-AteaWindowsMP.ps1 index cec6e56..466fa36 100644 --- a/Released/Install-AteaWindowsMP.ps1 +++ b/Released/Install-AteaWindowsMP.ps1 @@ -28,27 +28,51 @@ Defaults to the local computer. Set this to connect to a different SCOM Manageme #> [CmdletBinding()] param( - [ValidateSet("Stable","Latest")][string] $Version, + [Parameter(Mandatory = $true)] + [ValidateSet("Stable","Latest")] [string] $Version, [switch] $ImportMP, [string] $OMMSComputerName = "." ) -[string] $developURL = "https://github.com/stegenfeldt/Atea.Windows/raw/develop/Released/Atea.Windows.Installer.msi" -[string] $masterURL = "https://github.com/stegenfeldt/Atea.Windows/raw/master/Released/Atea.Windows.Installer.msi" +$Error.Clear() +[string[]] $mpFiles = @( + "Atea.Windows.Library.mp", + "Atea.Windows.Server.Monitoring.mp", + "Atea.Windows.Service.Monitoring.mp", + "Atea.Windows.File.Monitoring.mp" +) + +[string] $developURL = "https://github.com/stegenfeldt/Atea.Windows/raw/develop/Released/" +[string] $masterURL = "https://github.com/stegenfeldt/Atea.Windows/raw/master/Released/" [string] $installDir = "$(${env:ProgramFiles(x86)})\System Center Management Packs\Atea.Windows\" -[string] $msiFilePath = "$($env:TEMP)\Atea.Windows.Installer.msi" - -[string] $packageName = "Atea Windows - MP Package" - -if ($Version = "Stable") { - Invoke-WebRequest -Uri $masterURL -OutFile $msiFilePath - if (Get-Package -Name $packageName -ErrorAction SilentlyContinue) {Uninstall-Package -Name $packageName -Force} - Install-Package -Name $msiFilePath -Force -} elseif ($Version = "Latest") { - Invoke-WebRequest -Uri $developURL -OutFile $msiFilePath - if (Get-Package -Name $packageName -ErrorAction SilentlyContinue) {Uninstall-Package -Name $packageName -Force} - Install-Package -Name $msiFilePath -Force +$startLocation = Get-Location + +if ((Test-Path $installDir) -eq $false) { + if (!(New-Item -Path $installDir -ItemType Directory -Force -ErrorAction SilentlyContinue)) { + Write-Host "Unable to create directory." -ForegroundColor Red + Write-Host "Using current directory instead." + $installDir = "$($Script:PWD.Path)\" + } +} + +foreach ($mpFile in $mpFiles) { + switch ($Version) { + "Stable" { + $mpFilePath = $installDir + $mpFile + $mpFileURL = $masterURL + $mpFile + } + "Latest" { + $mpFilePath = $installDir + $mpFile + $mpFileURL = $developURL + $mpFile + } + default { + $mpFilePath = $installDir + $mpFile + $mpFileURL = $masterURL + $mpFile + } + } + Write-Verbose "Saving $mpFileURL to $mpFilePath" + Invoke-WebRequest -Uri $mpFileURL -OutFile $mpFilePath } if ($ImportMP -and (($Version = "Stable") -or ($Version = "Latest"))) { @@ -56,5 +80,165 @@ if ($ImportMP -and (($Version = "Stable") -or ($Version = "Latest"))) { New-SCOMManagementGroupConnection -ComputerName $OMMSComputerName $mps = Get-SCOMManagementPack -ManagementPackFile (Get-ChildItem -Path $installDir -Filter "*.mp").FullName + Write-Verbose "Importing managementpacks to $((Get-SCOMManagementGroup).Name)" Import-SCOMManagementPack -ManagementPack $mps -Verbose } + +# SIG # Begin signature block +# MIIdGQYJKoZIhvcNAQcCoIIdCjCCHQYCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB +# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR +# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU2Ocvbmr8ERmgRnPwUnP5QWcG +# 4pGgghg5MIIE3jCCA8agAwIBAgIQazJqDwMo03odUwv9I71I4jANBgkqhkiG9w0B +# AQsFADB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dp +# ZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +# MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMB4XDTE1MTAyOTEx +# MzAyOVoXDTI3MDYwOTExMzAyOVowgYAxCzAJBgNVBAYTAlBMMSIwIAYDVQQKDBlV +# bml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLDB5DZXJ0dW0gQ2VydGlm +# aWNhdGlvbiBBdXRob3JpdHkxJDAiBgNVBAMMG0NlcnR1bSBDb2RlIFNpZ25pbmcg +# Q0EgU0hBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALfbqNjI47za +# 2oO6ub/W1VdTQbdAuhcMRJXU6WY7f7S+kKOUCaWtISAXgEa0QyY+jksaZOwOQDJD +# /IKf/0ot6pTdWhE2i2Hv7BbUSQPY513DZVvyTgsrw8FT+kAtwqszJAWBcH7Ih0yf +# 0YDCGHsOFL1OA0PLKEiwLeY23xs9i8OMnTee4QbXJVDfeT3at1/rRr52KDa4AgBG +# A9A0G3i0KMdRx8iVP26NiRjcSfHCDxr0gYHHbdQEd8Uhoy5T+XfP3Kmbw8Hl1Wcv +# MbzAwmicSpblH/HzSDUO9uSxxe+HgDrigAw0nfoUZHHkHKGqss8Ap+M3cvlArZ4o +# lQINzpDjW8UCAwEAAaOCAVMwggFPMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +# FMB7tMi3blanCUia+HJP19ckLDY+MB8GA1UdIwQYMBaAFAh2zcsH/yT2xc3tu5C8 +# 4oQ3RnX3MA4GA1UdDwEB/wQEAwIBBjATBgNVHSUEDDAKBggrBgEFBQcDAzAvBgNV +# HR8EKDAmMCSgIqAghh5odHRwOi8vY3JsLmNlcnR1bS5wbC9jdG5jYS5jcmwwawYI +# KwYBBQUHAQEEXzBdMCgGCCsGAQUFBzABhhxodHRwOi8vc3ViY2Eub2NzcC1jZXJ0 +# dW0uY29tMDEGCCsGAQUFBzAChiVodHRwOi8vcmVwb3NpdG9yeS5jZXJ0dW0ucGwv +# Y3RuY2EuY2VyMDkGA1UdIAQyMDAwLgYEVR0gADAmMCQGCCsGAQUFBwIBFhhodHRw +# Oi8vd3d3LmNlcnR1bS5wbC9DUFMwDQYJKoZIhvcNAQELBQADggEBAKrlP3ZUAkxw +# DimpOZYGDzG3C/Gmi1L7EI9PQluMvTEjAWad6CmhTcNQ+vf4RQ4dgtf8/qYyBHP9 +# cezMiA+jkgjFgVgC/QtpO824P0k90I0cExRoLpsNmq2wGeKe0nw5d4hvI/17hPxE +# bbW6a3CSVWyUsdg3/alZHbRjstwTzXiOJTXBmo83hC7URczj9cyNc6jjOm3nlZRw +# V5FQtm3vc3JPLwKHYOLqIqHtPv3Ri2aNLnJtT8ZdNe6TqJjSZ2rp2hnNAoP5dPxf +# ehgEKB7dIjM7dmxHBV3VUv4OunbzgxDHbjBfp2DH+nQnMZsog+0hihvxI1KE7ZW8 +# rTqlo0IBnbwwggYUMIIE/KADAgECAhBurXO+EeW89wo8twyKIm/WMA0GCSqGSIb3 +# DQEBCwUAMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UECgwZVW5pemV0byBUZWNobm9s +# b2dpZXMgUy5BLjEnMCUGA1UECwweQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9y +# aXR5MSQwIgYDVQQDDBtDZXJ0dW0gQ29kZSBTaWduaW5nIENBIFNIQTIwHhcNMTYx +# MDI3MDkxOTM2WhcNMTcxMDI3MDkxOTM2WjCBjTELMAkGA1UEBhMCU0UxHjAcBgNV +# BAoMFU9wZW4gU291cmNlIERldmVsb3BlcjExMC8GA1UEAwwoT3BlbiBTb3VyY2Ug +# RGV2ZWxvcGVyLCBTYW11ZWwgVGVnZW5mZWxkdDErMCkGCSqGSIb3DQEJARYcc2Ft +# dWVsLnRlZ2VuZmVsZHRAaGFydGF0aS5zZTCCASIwDQYJKoZIhvcNAQEBBQADggEP +# ADCCAQoCggEBANwPjeTu0SLUiZc1k8pkKP8IZk7Id0obvTTQeXmp9xhvxsypLJUk +# eC33s5avefEjOJVf8oYW99XGUyYdgcJO22XWkxIq5uWbN+idhxI13kcwGTX9xp0a +# pH6FCvDkraCwtqmUSEl1dISOY4JBv1pMRf+919K/7qEQW7YH9Cl/3nH/qYTpUMkG +# TUwY58YB8qUwxCVa8A0w4FY0rHwx7Ds4VPWwq8zbPEKX7OO7HBQ2tQb4tc4Yuq5v +# HY5o60zPE8ZuYJllOfn9p6TFUBSQ3T2+zX14fF/Wz3cIfwDEzVZ1jX10CuF81yxP +# ihgdxOxI5ujh/jfJsS8svmsTrmiuODLdO00CAwEAAaOCAnkwggJ1MAwGA1UdEwEB +# /wQCMAAwMgYDVR0fBCswKTAnoCWgI4YhaHR0cDovL2NybC5jZXJ0dW0ucGwvY3Nj +# YXNoYTIuY3JsMHEGCCsGAQUFBwEBBGUwYzArBggrBgEFBQcwAYYfaHR0cDovL2Nz +# Y2FzaGEyLm9jc3AtY2VydHVtLmNvbTA0BggrBgEFBQcwAoYoaHR0cDovL3JlcG9z +# aXRvcnkuY2VydHVtLnBsL2NzY2FzaGEyLmNlcjAfBgNVHSMEGDAWgBTAe7TIt25W +# pwlImvhyT9fXJCw2PjAdBgNVHQ4EFgQUlV5XwtpXLs0CQdomBbg3c6JM0xcwHQYD +# VR0SBBYwFIESY3NjYXNoYTJAY2VydHVtLnBsMA4GA1UdDwEB/wQEAwIHgDCCATgG +# A1UdIASCAS8wggErMIIBJwYFZ4EMAQQwggEcMCUGCCsGAQUFBwIBFhlodHRwczov +# L3d3dy5jZXJ0dW0ucGwvQ1BTMIHyBggrBgEFBQcCAjCB5TAgFhlVbml6ZXRvIFRl +# Y2hub2xvZ2llcyBTLkEuMAMCAQEagcBVc2FnZSBvZiB0aGlzIGNlcnRpZmljYXRl +# IGlzIHN0cmljdGx5IHN1YmplY3RlZCB0byB0aGUgQ0VSVFVNIENlcnRpZmljYXRp +# b24gUHJhY3RpY2UgU3RhdGVtZW50IChDUFMpIGluY29ycG9yYXRlZCBieSByZWZl +# cmVuY2UgaGVyZWluIGFuZCBpbiB0aGUgcmVwb3NpdG9yeSBhdCBodHRwczovL3d3 +# dy5jZXJ0dW0ucGwvcmVwb3NpdG9yeS4wEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJ +# KoZIhvcNAQELBQADggEBAIkXhtrsJL9eEUKfia5fS1s5S5RI3JlLV0sFFl72zvGV +# F2bxxQkAf8xh30ft5N5N7ZwM3jDc52Q+vjttiXsBwTkqId2MgF8p7YvEGTMoDQiU +# rYOB82QY3Fbdz3dKViRi7/xm6aUHNsWmw/fUWZC8HAncRTQr5t35q3XmmFR+Xc+W +# Qgpfpjqbge9K2MEhLU6/wIUnqLsXXz3fHVEMwKqO6rQKo8nHUNGK9wxzZhBZIQJh +# Dw+c0KJl7k4Avqqriv/NtkwSYepgV1tCU2wFcwTiwuuUGe3rfgrW1vT5Fb7D3ddw +# gVj1HZNtmWcP9eRF2Uv5P6iblqN+H557h3yHYgR5QSkwggZqMIIFUqADAgECAhAD +# AZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMRUw +# EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +# ITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAeFw0xNDEwMjIwMDAw +# MDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREwDwYDVQQKEwhEaWdp +# Q2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJlc3BvbmRlcjCCASIw +# DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CCNeDg9sYq5kl1O8xu +# 4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4XpX6X51Id0iEQ7Gcnl +# 9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9Enh1DqZbFP1FI46G +# RFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu5uc0LzF3gTAfuzYB +# je8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDIjegEYNu8c3T6Ttj+ +# qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawCwO+k8IkRj3cCAwEA +# AaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB +# /wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGhBglghkgBhv1sBwEw +# ggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMIIB +# ZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAAbwBmACAAdABoAGkA +# cwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUA +# cwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgAZQAgAEQAaQBnAGkA +# QwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkA +# aQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4AdAAgAHcAaABpAGMA +# aAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAAYQBuAGQAIABhAHIA +# ZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIAZQBpAG4AIABiAHkA +# IAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAfBgNVHSMEGDAWgBQV +# ABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJMp1KKnkag0v0HonB +# yn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0Rp +# Z2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6Ly9jcmw0LmRpZ2lj +# ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcGCCsGAQUFBwEBBGsw +# aTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUF +# BzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVk +# SURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNNsiaBXJuGziMgD4CH +# 5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3+puxnSR+/iCkV61b +# t5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i2fAnPTgdKG86Ugnw +# 7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHdFMoVXZJB2vkPgdGZ +# dA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sKHOWV2q7ELlmgYd3a +# 822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvjjz3Kr2qNe9zYRDCC +# Bs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZIhvcNAQEFBQAwZTEL +# MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +# LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290 +# IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFowYjELMAkGA1UEBhMC +# VVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0 +# LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBDQS0xMIIBIjANBgkq +# hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBzQHDSnlZUXKnE0kEG +# j8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r7a2wcTHrzzpADEZN +# k+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD/6b3+6LNb3Mj/qxW +# BZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z8rwMK5nQxl0SQoHh +# g26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2zkBdXPao8S+v7Iki +# 8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9BwSiCQIDAQABo4ID +# ejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsGAQUFBwMBBggrBgEF +# BQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCCAdIGA1UdIASCAckw +# ggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cu +# ZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0wggFkBggrBgEFBQcC +# AjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgAaQBzACAAQwBlAHIA +# dABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQAZQBzACAAYQBjAGMA +# ZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcAaQBDAGUAcgB0ACAA +# QwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwAeQBpAG4AZwAgAFAA +# YQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkAYwBoACAAbABpAG0A +# aQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEAcgBlACAAaQBuAGMA +# bwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIAeQAgAHIAZQBmAGUA +# cgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQIMAYBAf8CAQAweQYI +# KwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j +# b20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp +# Q2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgwOqA4oDaGNGh0dHA6 +# Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmww +# OqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ +# RFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+Vw0rZwLNMB8GA1Ud +# IwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3DQEBBQUAA4IBAQBG +# UD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKyXGGinJXDUOSCuSPR +# ujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+erYs37iy2QwsDStZS9 +# Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+cdkvtX8JLFuRLcEwA +# iR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeSDY2xaYxP+1ngIw/S +# qq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGtSTGDR5V3cdyxG0tL +# HBCcdxTBnU8vWpUIKRAmMYIESjCCBEYCAQEwgZUwgYAxCzAJBgNVBAYTAlBMMSIw +# IAYDVQQKDBlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLDB5DZXJ0 +# dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxJDAiBgNVBAMMG0NlcnR1bSBDb2Rl +# IFNpZ25pbmcgQ0EgU0hBMgIQbq1zvhHlvPcKPLcMiiJv1jAJBgUrDgMCGgUAoHgw +# GAYKKwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGC +# NwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQx +# FgQUa/R0nwlVeyne5Vbw6COxLmsNVwwwDQYJKoZIhvcNAQEBBQAEggEAmgkqvheB +# qmFWz3l8ZRQ/rJ1pYAIcpJyiJuyhr5WRumWLQuY+EFqumL00eRiAUDX8VJV3eCFM +# 3rojWPXbPFdOmA3HLaaL0spBS0HMSHivgIw+nGP9emNDjoENcTiZQVeld2cwEslk +# 1VTKwDrxOqikbfxCpKjkDNCj800Uu6KGkmR4pY/dpZ8/aUHQJBgA1bggkmPO4FCy +# eWi9cBUjE2Fv6NV4c02Ob06yOqnDqeRWpWOsJiL3fzlO0ELswYm7zRPrjF7Ell/K +# p+2a6YVceAbuN+hewBeCh6AQ8GOv+AReRdzn2FhnJPXtxfxn3CKqhPI2OEakp1TF +# KfNWh6HYlPA+A6GCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJ +# BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k +# aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQ +# AwGaAjr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqG +# SIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTcwNDA2MTMwMDAwWjAjBgkqhkiG9w0B +# CQQxFgQUiytB1wxiYtV0tXKzdsWvzY8/RLMwDQYJKoZIhvcNAQEBBQAEggEAA81G +# vmmZtrwxKybdjFwanXGUasZQKZVFuB5I7fPRx+U5v4qCxaWYupfisKOhKmftIMFW +# +6zW1aq6TVVdYOjxtftkigQ962Q/vgH+aw7s0+PFm/s7+AdSMSUEq2ZT0x/VaWYB +# X53VXBpgwdJI7gTadryH2zSf8MMkfZKLMKDU+j6YdfhUH950IC0cELDc/PolQoQu +# PDqiSv+jmzTMGVsdjVRo2iiT6cW/dDJ+bvGhzPPxk3wHhYahgHJFrYVgHvZxn2PY +# dDvL8hsdJfKoc6FZ2Irjvn0Ud1Sb4bsyKghx+WFPOvIV/Y3RRJ9Ljog79X5HX19m +# 2UCBHdjyddFDobvMYg== +# SIG # End signature block diff --git a/Released/event.reg b/Released/event.reg new file mode 100644 index 0000000..807ceb3 Binary files /dev/null and b/Released/event.reg differ diff --git a/_Scripts/PostBuild.ps1 b/_Scripts/PostBuild.ps1 new file mode 100644 index 0000000..5bb9678 --- /dev/null +++ b/_Scripts/PostBuild.ps1 @@ -0,0 +1,7 @@ +param ( + [string] $FilePath +) + +#signtool sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /sha1 5E1D01C6F02199D1A39D806EB17A961F5C476EE2 "$(OutDir)$(TargetFileName)" +Set-AuthenticodeSignature -Certificate (dir Cert:\CurrentUser\My\5E1D01C6F02199D1A39D806EB17A961F5C476EE2) -TimestampServer "http://timestamp.digicert.com" -FilePath "$($FilePath)" +Set-AuthenticodeSignature -Certificate (dir Cert:\CurrentUser\My\5E1D01C6F02199D1A39D806EB17A961F5C476EE2) -TimestampServer "http://timestamp.digicert.com" -FilePath "$($FilePath.Substring(0,$FilePath.LastIndexOfAny("\"))+"\Setup.exe")" diff --git a/_Scripts/azure-pipelines-extinstall.ps1 b/_Scripts/azure-pipelines-extinstall.ps1 new file mode 100644 index 0000000..d8eeb57 --- /dev/null +++ b/_Scripts/azure-pipelines-extinstall.ps1 @@ -0,0 +1,17 @@ +$vsaeUrl = "https://download.microsoft.com/download/4/4/6/446B60D0-4409-4F94-9433-D83B3746A792/VisualStudioAuthoringConsole_x64.msi" +$vsaeFileName = "VisualStudioAuthoringConsole_x64.msi" +$vsaePackageName = "System Center Visual Studio Authoring Extensions" + +Invoke-WebRequest -Uri $vsaeUrl -Method Get -OutFile $vsaeFileName -Verbose + +$vsaeInstalled = Get-Package -IncludeWindowsInstaller -Name $vsaePackageName -Verbose +if (!$vsaeInstalled) { + Write-Host "VSAE Not Installed!" + Write-Host "Attempting install..." + Install-Package -InputObject (Find-Package -Name ".\$vsaeFileName") -Verbose +} else { + Write-Host "VSAE Already installed!" +} + +Write-Host "Copying SignKey..." +Copy-Item -Path $env:DOWNLOADSECUREFILE_SECUREFILEPATH -Destination ".\" -Verbose \ No newline at end of file diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 0000000..badbd87 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,34 @@ +# .NET Desktop +# Build and run tests for .NET Desktop or Windows classic desktop solutions. +# Add steps that publish symbols, save build artifacts, and more: +# https://docs.microsoft.com/azure/devops/pipelines/apps/windows/dot-net + +pool: + vmImage: 'VS2017-Win2016' + +variables: + solution: '**/*.sln' + buildPlatform: #'Any CPU' + buildConfiguration: 'Release' + +steps: +- task: NuGetToolInstaller@0 + +- task: NuGetCommand@2 + inputs: + restoreSolution: '$(solution)' + +- task: DownloadSecureFile@1 + inputs: + secureFile: 'AteaST.snk' + +- task: Powershell@2 + inputs: + targetType: filePath + filePath: '$(Build.SourcesDirectory)\_Scripts\azure-pipelines-extinstall.ps1' + +- task: VSBuild@1 + inputs: + solution: '$(solution)' + platform: '$(buildPlatform)' + configuration: '$(buildConfiguration)' \ No newline at end of file diff --git a/docs/Files/FileAgeMonitoring_Example1.reg b/docs/Files/FileAgeMonitoring_Example1.reg new file mode 100644 index 0000000..c147159 Binary files /dev/null and b/docs/Files/FileAgeMonitoring_Example1.reg differ