Added Files

This commit is contained in:
DistractADD
2021-07-06 13:16:46 +10:00
parent f2475a3bdd
commit cfddd4fad2
393 changed files with 65842 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
RuleID,RuleDescription,RuleAction
75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84, Block Office applications from injecting into other processes, Enabled
3B576869-A4EC-4529-8536-B80A7769E899, Block Office applications from creating executable content, Enabled
D4F940AB-401B-4EfC-AADC-AD5F3C50688A, Block Office applications from creating child processes, Enabled
D3E037E1-3EB8-44C8-A917-57927947596D, Impede JavaScript and VBScript to launch executables, Enabled
5BEB7EFE-FD9A-4556-801D-275E5FFC04CC, Block execution of potentially obfuscated script, Enabled
BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550, Block executable content from email client and webmail, Enabled
92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B, Block Win32 imports from Macro code in Office, Enabled
c1db55ab-c21a-4637-bb3f-a12568109d35, Use advanced protection against ransomware, Enabled
9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2, Block credential stealing from the Windows local security authority subsystem (lsass.exe), Enabled
d1e49aac-8f56-4280-b9ba-993a6d77406c, Block process creations originating from PSExec and WMI commands, Enabled
b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4, Block untrusted and unsigned processes that run from USB, Enabled
26190899-1602-49e8-8b27-eb1d0a1ce869, Block Office communication applications from creating child processes, AuditMode
7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c, Block Adobe Reader from creating child processes, Enabled
e6db77e5-3df2-4cf1-b95a-636979351e5b, Block persistence through WMI event subscription, Enabled
01443614-cd74-433a-b99e-2ecdc07bfc25, Block executable files from running unless they meet a prevalence age or trusted list criteria, AuditMode
1 RuleID RuleDescription RuleAction
2 75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84 Block Office applications from injecting into other processes Enabled
3 3B576869-A4EC-4529-8536-B80A7769E899 Block Office applications from creating executable content Enabled
4 D4F940AB-401B-4EfC-AADC-AD5F3C50688A Block Office applications from creating child processes Enabled
5 D3E037E1-3EB8-44C8-A917-57927947596D Impede JavaScript and VBScript to launch executables Enabled
6 5BEB7EFE-FD9A-4556-801D-275E5FFC04CC Block execution of potentially obfuscated script Enabled
7 BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550 Block executable content from email client and webmail Enabled
8 92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B Block Win32 imports from Macro code in Office Enabled
9 c1db55ab-c21a-4637-bb3f-a12568109d35 Use advanced protection against ransomware Enabled
10 9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2 Block credential stealing from the Windows local security authority subsystem (lsass.exe) Enabled
11 d1e49aac-8f56-4280-b9ba-993a6d77406c Block process creations originating from PSExec and WMI commands Enabled
12 b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4 Block untrusted and unsigned processes that run from USB Enabled
13 26190899-1602-49e8-8b27-eb1d0a1ce869 Block Office communication applications from creating child processes AuditMode
14 7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c Block Adobe Reader from creating child processes Enabled
15 e6db77e5-3df2-4cf1-b95a-636979351e5b Block persistence through WMI event subscription Enabled
16 01443614-cd74-433a-b99e-2ecdc07bfc25 Block executable files from running unless they meet a prevalence age or trusted list criteria AuditMode

View File

@@ -0,0 +1,676 @@
#requires -Version 3.0 -Modules ConfigDefender, NetSecurity
<#
.SYNOPSIS
Bootstrap Microsoft Defender configuration
.DESCRIPTION
Bootstrap Microsoft Defender configuration, optimize and tweak Windows 10 protection and security
.PARAMETER CsvPath
The CSV with the configuration.
This is optional. Defaults are in the Script.
.PARAMETER Force
Enforce to apply the customize attack surface reduction rules
.EXAMPLE
PS C:\> .\Bootstrap-MicrosoftDefenderConfiguration.ps1
Bootstrap Microsoft Defender configuration, optimize and tweak Windows 10 Protection
.EXAMPLE
PS C:\> .\Bootstrap-MicrosoftDefenderConfiguration.ps1 -Verbose -Force
Bootstrap Microsoft Defender configuration, optimize and tweak Windows 10 Protection
.EXAMPLE
PS C:\> .\Bootstrap-MicrosoftDefenderConfiguration.ps1 -Verbose
Bootstrap Microsoft Defender configuration, optimize and tweak Windows 10 Protection
.LINK
https://docs.microsoft.com/en-us/powershell/module/defender/index?view=win10-ps
.LINK
https://github.com/jhochwald/PowerShell-collection/blob/master/Misc/Optimize-MicrosoftDefenderExclusions.ps1
.LINK
https://docs.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-atp/enable-exploit-protection
.LINK
https://docs.microsoft.com/en-us/powershell/module/defender/set-mppreference?view=win10-ps
.LINK
https://docs.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-atp/customize-attack-surface-reduction
.LINK
https://support.microsoft.com/en-us/help/822158/virus-scanning-recommendations-for-enterprise-computers-that-are-runni
.LINK
https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-antivirus/enable-cloud-protection-windows-defender-antivirus
.LINK
https://demo.wd.microsoft.com/?ocid=cx-wddocs-testground
.NOTES
Please review the settings, please tweak the rules file (or modify the default rule set here)
You need to run this in an elevated PowerShell!
I use this during the bootstrap process of Windows systems.
Most of the settings here is also enforced by some of our Group Policies and we also have a lot of it configured via MDM CSPs (InTune).
This script is only a quick hack to harden (and secure) any new system, even if it is not managed afterwords.
#>
[CmdletBinding(ConfirmImpact = 'Low',
SupportsShouldProcess)]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[Alias('RulesCsv')]
[string]
$CsvPath = '.\Bootstrap-MicrosoftDefenderConfiguration.csv',
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[Alias('EnforceRule')]
[switch]
$Force = $null
)
begin
{
# Create a new Mail Object
$AttackSurfaceReductionRuleList = @()
#region CsvHandler
if (Test-Path -Path $CsvPath -ErrorAction SilentlyContinue)
{
#region ImportCsv
Write-Verbose -Message ('Import the attack surface reduction settings from ' + $CsvPath)
$AttackSurfaceReductionRuleList = (Import-Csv -Path $CsvPath -Delimiter ',' -Encoding UTF8)
#endregion ImportCsv
}
else
{
#region DefaultCsv
Write-Verbose -Message 'Use the attack surface reduction default settings'
# Create a virtual CSV File (Quick hack: To keep it plain and simple to maintain)
$RuleDefaults = 'RuleID,RuleDescription,RuleAction
75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84, Block Office applications from injecting into other processes, Enabled
3B576869-A4EC-4529-8536-B80A7769E899, Block Office applications from creating executable content, Enabled
D4F940AB-401B-4EfC-AADC-AD5F3C50688A, Block Office applications from creating child processes, Enabled
D3E037E1-3EB8-44C8-A917-57927947596D, Impede JavaScript and VBScript to launch executable, Enabled
5BEB7EFE-FD9A-4556-801D-275E5FFC04CC, Block execution of potentially obfuscated script, Enabled
BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550, Block executable content from email client and webmail, Enabled
92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B, Block Win32 imports from Macro code in Office, Enabled
c1db55ab-c21a-4637-bb3f-a12568109d35, Use advanced protection against ransomware, Enabled
9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2, Block credential stealing from the Windows local security authority subsystem (lsass.exe), Enabled
d1e49aac-8f56-4280-b9ba-993a6d77406c, Block process creations originating from PSExec and WMI commands, Enabled
b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4, Block untrusted and unsigned processes that run from USB, Enabled
26190899-1602-49e8-8b27-eb1d0a1ce869, Block Office communication applications from creating child processes, AuditMode
7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c, Block Adobe Reader from creating child processes, Enabled
e6db77e5-3df2-4cf1-b95a-636979351e5b, Block persistence through WMI event subscription, Enabled
01443614-cd74-433a-b99e-2ecdc07bfc25, Block executable files from running unless they meet a prevalence age or trusted list criteria, AuditMode'
# Import the virtual CSV File
$AttackSurfaceReductionRuleList = (ConvertFrom-Csv -InputObject $RuleDefaults -Delimiter ',')
#endregion DefaultCsv
}
#endregion CsvHandler
}
process
{
#region SetMpPreference
#region EnableNetworkProtection
Write-Verbose -Message 'Network protection helps to prevent employees from using any application to access dangerous domains that may host phishing scams, exploits, and other malicious content on the Internet'
$null = (Set-MpPreference -EnableNetworkProtection Enabled -Force -ErrorAction Continue)
#endregion EnableNetworkProtection
#region EnableControlledFolderAccess
Write-Verbose -Message 'Controlled folder access helps you protect valuable data from malicious apps and threats, such as ransomware'
$null = (Set-MpPreference -EnableControlledFolderAccess Enabled -Force -ErrorAction Continue)
#endregion EnableControlledFolderAccess
#region SignatureScheduleDay
Write-Verbose -Message 'Specifies the day of the week on which to check for definition updates'
$null = (Set-MpPreference -SignatureScheduleDay Everyday -Force -ErrorAction Continue)
#endregion SignatureScheduleDay
#region SignatureScheduleTime
Write-Verbose -Message 'Specifies the time of day, as the number of minutes after midnight, to check for definition updates'
$null = (Set-MpPreference -SignatureScheduleTime 320 -Force -ErrorAction Continue)
#endregion SignatureScheduleTime
#region DisableArchiveScanning
Write-Verbose -Message 'Indicates whether to scan archive files for malicious and unwanted software'
$null = (Set-MpPreference -DisableArchiveScanning $true -Force -ErrorAction Continue)
#endregion DisableArchiveScanning
#region DisableAutoExclusions
Write-Verbose -Message 'Indicates whether to disable the Automatic Exclusions feature for the server'
$null = (Set-MpPreference -DisableAutoExclusions $false -Force -ErrorAction Continue)
#endregion DisableAutoExclusions
#region DisableBehaviorMonitoring
Write-Verbose -Message 'Indicates whether to enable behavior monitoring'
$null = (Set-MpPreference -DisableBehaviorMonitoring $true -Force -ErrorAction Continue)
#endregion DisableBehaviorMonitoring
#region DisableBlockAtFirstSeen
Write-Verbose -Message 'Indicates whether to enable block at first seen'
$null = (Set-MpPreference -DisableBlockAtFirstSeen $true -Force -ErrorAction Continue)
#endregion DisableBlockAtFirstSeen
#region DisableCatchupFullScan
Write-Verbose -Message 'Indicates whether Windows Defender runs catch-up scans for scheduled full scans'
$null = (Set-MpPreference -DisableCatchupFullScan $true -Force -ErrorAction Continue)
#endregion DisableCatchupFullScan
#region DisableCatchupQuickScan
Write-Verbose -Message 'Indicates whether Windows Defender runs catch-up scans for scheduled quick scans'
$null = (Set-MpPreference -DisableCatchupQuickScan $true -Force -ErrorAction Continue)
#endregion DisableCatchupQuickScan
#region DisableEmailScanning
Write-Verbose -Message 'Indicates whether Windows Defender parses the mailbox and mail files, according to their specific format, in order to analyze mail bodies and attachments'
$null = (Set-MpPreference -DisableEmailScanning $false -Force -ErrorAction Continue)
#endregion DisableEmailScanning
#region DisableIOAVProtection
Write-Verbose -Message 'Indicates whether Windows Defender scans all downloaded files and attachments (e.g. Downloads)'
$null = (Set-MpPreference -DisableIOAVProtection $true -Force -ErrorAction Continue)
#endregion DisableIOAVProtection
#region DisableIntrusionPreventionSystem
Write-Verbose -Message 'Indicates whether to configure network protection against exploitation of known vulnerabilities'
$null = (Set-MpPreference -DisableIntrusionPreventionSystem $false -Force -ErrorAction Continue)
#endregion DisableIntrusionPreventionSystem
#region DisablePrivacyMode
Write-Verbose -Message 'Indicates whether to disable privacy mode. Privacy mode prevents users, other than administrators, from displaying threat history'
$null = (Set-MpPreference -DisablePrivacyMode $false -Force -ErrorAction Continue)
#endregion DisablePrivacyMode
#region DisableRealtimeMonitoring
Write-Verbose -Message 'Indicates whether to use real-time protection'
$null = (Set-MpPreference -DisableRealtimeMonitoring $false -Force -ErrorAction Continue)
#endregion DisableRealtimeMonitoring
#region CheckForSignaturesBeforeRunningScan
Write-Verbose -Message 'Enable checking signatures before scanning'
$null = (Set-MpPreference -CheckForSignaturesBeforeRunningScan 1 -Force -ErrorAction Continue)
#endregion CheckForSignaturesBeforeRunningScan
#region DisableRemovableDriveScanning
Write-Verbose -Message 'Indicates whether to scan for malicious and unwanted software in removable drives, such as flash drives, during a full scan'
$null = (Set-MpPreference -DisableRemovableDriveScanning $true -Force -ErrorAction Continue)
#endregion DisableRemovableDriveScanning
#region DisableRestorePoint
Write-Verbose -Message 'Indicates whether to disable scanning of restore points'
$null = (Set-MpPreference -DisableRestorePoint $true -Force -ErrorAction Continue)
#endregion DisableRestorePoint
#region DisableScanningMappedNetworkDrivesForFullScan
Write-Verbose -Message 'Indicates whether to scan mapped network drives'
$null = (Set-MpPreference -DisableScanningMappedNetworkDrivesForFullScan $true -Force -ErrorAction Continue)
#endregion DisableScanningMappedNetworkDrivesForFullScan
#region DisableScanningNetworkFiles
Write-Verbose -Message 'Indicates whether to scan for network files'
$null = (Set-MpPreference -DisableScanningNetworkFiles $false -Force -ErrorAction Continue)
#endregion DisableScanningNetworkFiles
#region DisableScriptScanning
Write-Verbose -Message 'Specifies whether to disable the scanning of scripts during malware scans'
$null = (Set-MpPreference -DisableScriptScanning $false -Force -ErrorAction Continue)
#endregion DisableScriptScanning
#region HighThreatDefaultAction
Write-Verbose -Message 'Specifies which automatic remediation action to take for a high level threat'
$null = (Set-MpPreference -HighThreatDefaultAction Quarantine -Force -ErrorAction Continue)
#endregion HighThreatDefaultAction
#region LowThreatDefaultAction
Write-Verbose -Message 'Specifies which automatic remediation action to take for a low level threat'
$null = (Set-MpPreference -LowThreatDefaultAction Block -Force -ErrorAction Continue)
#endregion LowThreatDefaultAction
#region ModerateThreatDefaultAction
Write-Verbose -Message 'Specifies which automatic remediation action to take for a moderate level threat'
$null = (Set-MpPreference -ModerateThreatDefaultAction Quarantine -Force -ErrorAction Continue)
#endregion ModerateThreatDefaultAction
#region PUAProtection
Write-Verbose -Message 'Disable PUA Protection'
$null = (Set-MpPreference -PUAProtection Enabled -Force -ErrorAction Continue)
#endregion PUAProtection
#region QuarantinePurgeItemsAfterDelay
Write-Verbose -Message 'Specifies the number of days to keep items in the Quarantine folder'
$null = (Set-MpPreference -QuarantinePurgeItemsAfterDelay 30 -Force -ErrorAction Continue)
#endregion QuarantinePurgeItemsAfterDelay
#region RandomizeScheduleTaskTimes
Write-Verbose -Message 'Indicates whether to select a random time for the scheduled start and scheduled update for definitions'
$null = (Set-MpPreference -RandomizeScheduleTaskTimes $true -Force -ErrorAction Continue)
#endregion RandomizeScheduleTaskTimes
#region RealTimeScanDirection
Write-Verbose -Message 'Specifies scanning configuration for incoming and outgoing files on NTFS volumes'
$null = (Set-MpPreference -RealTimeScanDirection 0 -Force -ErrorAction Continue)
#endregion RealTimeScanDirection
#region RemediationScheduleDay
Write-Verbose -Message 'Specifies the day of the week on which to perform a scheduled full scan in order to complete remediation'
$null = (Set-MpPreference -RemediationScheduleDay Everyday -Force -ErrorAction Continue)
#endregion
#region RemediationScheduleTime
Write-Verbose -Message 'Specifies the time of day, as the number of minutes after midnight, to perform a scheduled scan'
$null = (Set-MpPreference -RemediationScheduleTime 120 -Force -ErrorAction Continue)
#endregion RemediationScheduleDay
#region ReportingAdditionalActionTimeOut
Write-Verbose -Message 'Specifies the number of minutes before a detection in the additional action state changes to the cleared state'
$null = (Set-MpPreference -ReportingAdditionalActionTimeOut 10080 -Force -ErrorAction Continue)
#endregion ReportingAdditionalActionTimeOut
#region ReportingCriticalFailureTimeOut
Write-Verbose -Message 'Specifies the number of minutes before a detection in the critically failed state changes to either the additional action state or the cleared state'
$null = (Set-MpPreference -ReportingCriticalFailureTimeOut 10080 -Force -ErrorAction Continue)
#endregion ReportingCriticalFailureTimeOut
#region ReportingNonCriticalTimeOut
Write-Verbose -Message 'Specifies the number of minutes before a detection in the non-critically failed state changes to the cleared state'
$null = (Set-MpPreference -ReportingNonCriticalTimeOut 11440 -Force -ErrorAction Continue)
#endregion ReportingNonCriticalTimeOut
#region ScanAvgCPULoadFactor
Write-Verbose -Message 'Specifies the maximum percentage CPU usage for a scan'
$null = (Set-MpPreference -ScanAvgCPULoadFactor 50 -Force -ErrorAction Continue)
#endregion ScanAvgCPULoadFactor
#region ScanOnlyIfIdleEnabled
Write-Verbose -Message 'Indicates whether to start scheduled scans only when the computer is not in use'
$null = (Set-MpPreference -ScanOnlyIfIdleEnabled $true -Force -ErrorAction Continue)
#endregion ScanOnlyIfIdleEnabled
#region ScanParameters
Write-Verbose -Message 'Specifies the scan type to use during a scheduled scan'
$null = (Set-MpPreference -ScanParameters 1 -Force -ErrorAction Continue)
#endregion ScanParameters
#region ScanPurgeItemsAfterDelay
Write-Verbose -Message 'Specifies the number of days to keep items in the scan history folder'
$null = (Set-MpPreference -ScanPurgeItemsAfterDelay 15 -Force -ErrorAction Continue)
#endregion ScanPurgeItemsAfterDelay
#region ScanScheduleDay
Write-Verbose -Message 'Specifies the day of the week on which to perform a scheduled scan'
$null = (Set-MpPreference -ScanScheduleDay Everyday -Force -ErrorAction Continue)
#endregion ScanScheduleDay
#region ScanScheduleQuickScanTime
Write-Verbose -Message 'Specifies the time of day, as the number of minutes after midnight, to perform a scheduled quick scan'
$null = (Set-MpPreference -ScanScheduleQuickScanTime 0 -Force -ErrorAction Continue)
#endregion ScanScheduleQuickScanTime
#region ScanScheduleTime
Write-Verbose -Message 'Specifies the time of day, as the number of minutes after midnight, to perform a scheduled scan'
$null = (Set-MpPreference -ScanScheduleTime 120 -Force -ErrorAction Continue)
#endregion ScanScheduleTime
#region SevereThreatDefaultAction
Write-Verbose -Message 'Specifies which automatic remediation action to take for a severe level threat'
$null = (Set-MpPreference -SevereThreatDefaultAction Quarantine -Force -ErrorAction Continue)
#endregion SevereThreatDefaultAction
#region SignatureAuGracePeriod
Write-Verbose -Message 'Specifies a grace period, in minutes, for the definition'
$null = (Set-MpPreference -SignatureAuGracePeriod 0 -Force -ErrorAction Continue)
#endregion SignatureAuGracePeriod
#region SignatureDisableUpdateOnStartupWithoutEngine
Write-Verbose -Message 'Indicates whether to initiate definition updates even if no antimalware engine is present'
$null = (Set-MpPreference -SignatureDisableUpdateOnStartupWithoutEngine $false -Force -ErrorAction Continue)
#endregion SignatureDisableUpdateOnStartupWithoutEngine
#region SignatureFirstAuGracePeriod
Write-Verbose -Message 'Specifies a grace period, in minutes, for the definition. If a definition successfully updates within this period, Windows Defender abandons any service initiated updates'
$null = (Set-MpPreference -SignatureFirstAuGracePeriod 120 -Force -ErrorAction Continue)
#endregion SignatureFirstAuGracePeriod
#region SignatureScheduleDay
Write-Verbose -Message 'Specifies the day of the week on which to check for definition updates'
$null = (Set-MpPreference -SignatureScheduleDay Everyday -Force -ErrorAction Continue)
#endregion SignatureScheduleDay
#region SignatureScheduleTime
Write-Verbose -Message 'Specifies the time of day, as the number of minutes after midnight, to check for definition updates'
$null = (Set-MpPreference -SignatureScheduleTime 165 -Force -ErrorAction Continue)
#endregion SignatureScheduleTime
#region SignatureUpdateCatchupInterval
Write-Verbose -Message 'Specifies the number of days after which Windows Defender requires a catch-up definition update'
$null = (Set-MpPreference -SignatureUpdateCatchupInterval 1 -Force -ErrorAction Continue)
#endregion SignatureUpdateCatchupInterval
#region SignatureUpdateInterval
Write-Verbose -Message 'Specifies the interval, in hours, at which to check for definition updates'
$null = (Set-MpPreference -SignatureUpdateInterval 12 -Force -ErrorAction Continue)
#endregion SignatureUpdateInterval
#region SubmitSamplesConsent
Write-Verbose -Message 'Specifies how Windows Defender checks for user consent for certain samples'
$null = (Set-MpPreference -SubmitSamplesConsent AlwaysPrompt -Force -ErrorAction Continue)
#endregion SubmitSamplesConsent
#region MAPSReporting MAPSReporting
Write-Verbose -Message 'Membership in Microsoft Active Protection Service Enable'
$null = (Set-MpPreference -MAPSReporting Advanced -Force -ErrorAction Continue)
#endregion MAPSReporting MAPSReporting
#region ThrottleLimit
Write-Verbose -Message 'Specifies the maximum number of concurrent operations that can be established to run the cmdlet'
$null = (Set-MpPreference -ThrottleLimit 0 -Force -ErrorAction Continue)
#endregion ThrottleLimit
#region UILockdown
Write-Verbose -Message 'Indicates whether to disable UI lock down mode'
$null = (Set-MpPreference -UILockdown $false -Force -ErrorAction Continue)
#endregion UILockdown
#region UnknownThreatDefaultAction
Write-Verbose -Message 'Specifies which automatic remediation action to take for an unknown level threat'
$null = (Set-MpPreference -UnknownThreatDefaultAction Block -Force -ErrorAction Continue)
#endregion UnknownThreatDefaultAction
#region SignatureFallbackOrder
Write-Verbose -Message 'Specifies the order in which to contact different definition update sources.'
$null = (Set-MpPreference -SignatureFallbackOrder 'MicrosoftUpdateServer | MMPC' -Force -ErrorAction Continue)
#endregion SignatureFallbackOrder
#region ControlledFolderAccessAllowedApplications
Write-Verbose -Message 'Setup the Controlled Folder Access Allowed Applications'
# Define a list of Applications to exclude - Fully Qualified
<#
I like to keep this list as short as possible
#>
$NewControlledFolderAccessAllowedApplications = @(
"$env:windir\System32\taskhostw.exe"
)
# Create a new Object
$AllControlledFolderAccessAllowedApplications = (New-Object -TypeName System.Collections.Generic.List[System.Object])
# Get the existing exclusions
$AllControlledFolderAccessAllowedApplications.Add((Get-MpPreference -ErrorAction SilentlyContinue | Select-Object -ExpandProperty ControlledFolderAccessAllowedApplications))
#region NewControlledFolderAccessAllowedApplicationsLoop
foreach ($NewControlledFolderAccessAllowedApplication in $NewControlledFolderAccessAllowedApplications)
{
if ($AllControlledFolderAccessAllowedApplications -notcontains $NewControlledFolderAccessAllowedApplication)
{
Write-Verbose -Message ('Add ' + $NewControlledFolderAccessAllowedApplication + ' to the Controlled Folder Access Allowed Applications list')
$AllControlledFolderAccessAllowedApplications.Add($NewControlledFolderAccessAllowedApplication)
}
}
#endregion NewControlledFolderAccessAllowedApplicationsLoop
# Make sure we have nothing doubled
$AllControlledFolderAccessAllowedApplications = ($AllControlledFolderAccessAllowedApplications | Sort-Object -Unique)
# Apply the new exclusion list. This will replace the complete list.
Write-Verbose -Message 'Apply the new Controlled Folder Access Allowed Applications list'
$null = (Set-MpPreference -ControlledFolderAccessAllowedApplications $AllControlledFolderAccessAllowedApplications -Force -ErrorAction Continue)
#endregion ControlledFolderAccessAllowedApplications
#region ExclusionPath
# Define a list of Applications to exclude - Fully Qualified
$NewExclusionPathList = @(
"$env:windir\SoftwareDistribution\DataStore\Datastore.edb",
"$env:windir\SoftwareDistribution\DataStore\Logs\Edb*.jrs",
"$env:windir\SoftwareDistribution\DataStore\Logs\Edb.chk",
"$env:windir\SoftwareDistribution\DataStore\Logs\Tmp.edb",
"$env:windir\Security\Database\*.edb",
"$env:windir\Security\Database\*.sdb",
"$env:windir\Security\Database\*.log",
"$env:windir\Security\Database\*.chk",
"$env:windir\Security\Database\*.jrs",
"$env:windir\Security\Database\*.xml",
"$env:windir\Security\Database\*.csv",
"$env:windir\Security\Database\*.cmtx",
"$env:ProgramData\ntuser.pol",
"$env:windir\System32\GroupPolicy\Machine\Registry.pol",
"$env:windir\System32\GroupPolicy\Machine\Registry.tmp",
"$env:windir\System32\GroupPolicy\User\Registry.pol",
"$env:windir\System32\GroupPolicy\User\Registry.tmp"
)
# Create a new Object
$AllExclusionPath = (New-Object -TypeName System.Collections.Generic.List[System.Object])
# Get the existing exclusions
$AllExclusionPath.Add((Get-MpPreference -ErrorAction SilentlyContinue | Select-Object -ExpandProperty ExclusionPath))
#region NewExclusionPathLoop
foreach ($NewExclusionPath in $NewExclusionPathList)
{
if ($AllExclusionPath -notcontains $NewExclusionPath)
{
Write-Verbose -Message ('Add ' + $NewExclusionPath + ' as path to exclude')
$AllExclusionPath.Add($NewExclusionPath)
}
}
#endregion NewExclusionPathLoop
# Make sure we have nothing doubled
$AllExclusionPath = ($AllExclusionPath | Sort-Object -Unique)
# Apply the new exclusion list. This will replace the complete list.
Write-Verbose -Message 'Apply the new Path to exclude list'
$null = (Set-MpPreference -ExclusionPath $AllExclusionPath -Force -ErrorAction Continue)
#endregion ExclusionPath
#region ExclusionProcess
# Define a list of Applications to exclude - Fully Qualified
$NewExclusionProcessList = @(
"$env:windir\System32\svchost.exe",
"$env:windir\System32\wuauclt.exe"
)
# Create a new Object
$AllExclusionProcess = (New-Object -TypeName System.Collections.Generic.List[System.Object])
# Get the existing exclusions
$AllExclusionProcess.Add((Get-MpPreference -ErrorAction SilentlyContinue | Select-Object -ExpandProperty ExclusionProcess))
#region NewExclusionProcessLoop
foreach ($NewExclusionProcess in $NewExclusionProcessList)
{
if ($AllExclusionProcess -notcontains $NewExclusionProcess)
{
Write-Verbose -Message ('Add ' + $NewExclusionProcess + ' as process to exclude')
$AllExclusionProcess.Add($NewExclusionProcess)
}
}
#endregion NewExclusionProcessLoop
# Make sure we have nothing doubled
$AllExclusionProcess = ($AllExclusionProcess | Sort-Object -Unique)
# Apply the new exclusion list. This will replace the complete list.
Write-Verbose -Message 'Apply the new Process to exclude list'
$null = (Set-MpPreference -ExclusionProcess $AllExclusionProcess -Force -ErrorAction Continue)
#endregion ExclusionProcess
#endregion SetMpPreference
#region ProcessMitigation
# Local Process Mitigation file
$ProcessMitigationFile = '.\ProcessMitigation.xml'
# Check if we have a local Process Mitigation file
if (-not (Test-Path -Path $ProcessMitigationFile -ErrorAction SilentlyContinue))
{
# Where to download the XML File?
$ProcessMitigationUri = 'https://demo.wd.microsoft.com/Content/ProcessMitigation.xml'
Write-Verbose -Message ('Downloading Process Mitigation file from ' + $ProcessMitigationUri)
# Download
$paramInvokeWebRequest = @{
Uri = $ProcessMitigationUri
OutFile = $ProcessMitigationFile
Method = 'Get'
ContentType = 'text/xml'
ErrorAction = 'Continue'
}
$null = (Invoke-WebRequest @paramInvokeWebRequest)
}
if (Test-Path -Path $ProcessMitigationFile -ErrorAction SilentlyContinue)
{
Write-Verbose -Message 'Enabling Exploit Protection'
# Apply the File
$null = (Set-ProcessMitigation -PolicyFilePath $ProcessMitigationFile -ErrorAction Continue)
# Cleanup
$paramRemoveItem = @{
Path = $ProcessMitigationFile
Force = $true
Confirm = $false
ErrorAction = 'Continue'
}
$null = (Remove-Item @paramRemoveItem)
}
else
{
Write-Warning -Message ('The local Process Mitigation file (' + $ProcessMitigationFile + ') is missing! Not enabling Exploit Protection.')
}
#endregion ProcessMitigation
#region WindowsDefenderSandbox
Write-Verbose -Message 'Turn on Windows Defender Sandbox'
$null = ([Environment]::SetEnvironmentVariable('MP_FORCE_USE_SANDBOX', 1, 'Machine'))
#endregion WindowsDefenderSandbox
#region AttackSurfaceReduction
#region GetAttackSurfaceReductionRulesIds
$AttackSurfaceReductionRulesIds = (Get-MpPreference -ErrorAction SilentlyContinue | Select-Object -ExpandProperty AttackSurfaceReductionRules_Ids)
#endregion GetAttackSurfaceReductionRulesIds
Write-Verbose -Message 'Enabling Attack Surface Reduction rules'
#region SetMpPreferenceDefaults
$AddMpPreferenceParameters = @{
ErrorAction = 'Stop'
Force = $true
}
#endregion SetMpPreferenceDefaults
#region RuleLoop
foreach ($AttackSurfaceReductionRule in $AttackSurfaceReductionRuleList)
{
#region SingleLoop
try
{
if (($Force) -or ($AttackSurfaceReductionRulesIds -notcontains $AttackSurfaceReductionRule.RuleID))
{
#region AppleTheRuleValue
Write-Verbose -Message ('Set ' + $AttackSurfaceReductionRule.RuleDescription + ' to ' + $AttackSurfaceReductionRule.RuleAction)
# Add some values
$AddMpPreferenceParameters.AttackSurfaceReductionRules_Ids = $AttackSurfaceReductionRule.RuleID
$AddMpPreferenceParameters.AttackSurfaceReductionRules_Actions = $AttackSurfaceReductionRule.RuleAction
# Apply the Rule
$null = (Add-MpPreference @AddMpPreferenceParameters)
#endregion AppleTheRuleValue
}
}
catch
{
#region ErrorHandler
# get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
$info | Out-String | Write-Verbose
Write-Warning -Message ('Unable to enable to Rule: ' + $AttackSurfaceReductionRule.RuleID + ' (' + $AttackSurfaceReductionRule.RuleDescription + ')')
#endregion ErrorHandler
}
#endregion SingleLoop
}
#endregion RuleLoop
#endregion AttackSurfaceReduction
#region ReloadRegistry
& "$env:windir\system32\rundll32.exe" USER32.DLL, UpdatePerUserSystemParameters , 1 , True
#endregion ReloadRegistry
#region EnableFirewall
Write-Verbose -Message 'Enable the Windows Firewall for all Profiles - Set the default to block everything'
$null = (Set-NetFirewallProfile -Profile Domain, Public, Private -Enabled True -DefaultInboundAction Block -LogBlocked True -Confirm:$false -ErrorAction Continue)
#endregion EnableFirewall
}
end
{
#region UpdateSignature
Write-Verbose -Message 'Update Defender'
$null = (Update-MpSignature)
#endregion UpdateSignature
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,29 @@
BSD 3-Clause License
Copyright (c) 2021, enabling Technology <http://enatec.io>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,476 @@
# Bootstrap Microsoft Defender configuration
Bootstrap Microsoft Defender configuration, optimize and tweak Windows 10 protection and security
## What it does
Several Microsoft Defender settings are configured.
### EnableNetworkProtection
Network protection helps to prevent employees from using any application to access dangerous domains that may host phishing scams, exploits, and other malicious content on the Internet
Set to: `Enabled`
### EnableControlledFolderAccess
Controlled folder access helps you protect valuable data from malicious apps and threats, such as ransomware
Set to: `Enabled`
### SignatureScheduleDay
Specifies the day of the week on which to check for definition updates.
Set to: `Everyday`
### SignatureScheduleTime
Specifies the time of day, as the number of minutes after midnight, to check for definition updates
Set to: `320`
### DisableArchiveScanning
Indicates whether to scan archive files for malicious and unwanted software
Set to: `true`
### DisableAutoExclusions
Indicates whether to disable the Automatic Exclusions feature for the server
Set to: `false`
### DisableBehaviorMonitoring
Indicates whether to enable behavior monitoring
Set to: `true`
Something I enable on a few systems only.
### DisableBlockAtFirstSeen
Indicates whether to enable block at first seen
Set to: `true`
### DisableCatchupFullScan
Indicates whether Windows Defender runs catch-up scans for scheduled full scans
Set to: `true`
### DisableCatchupQuickScan
Indicates whether Windows Defender runs catch-up scans for scheduled quick scans
Set to: `true`
### DisableEmailScanning
Indicates whether Windows Defender parses the mailbox and mail files, according to their specific format, in order to analyze mail bodies and attachments
Set to: `false`
### DisableIOAVProtection
Indicates whether Windows Defender scans all downloaded files and attachments (e.g. Downloads)
Set to: `true`
### DisableIntrusionPreventionSystem
Indicates whether to configure network protection against exploitation of known vulnerabilities
Set to: `false`
### DisablePrivacyMode
Indicates whether to disable privacy mode. Privacy mode prevents users, other than administrators, from displaying threat history
Set to: `false`
### DisableRealtimeMonitoring
Indicates whether to use real-time protection
Set to: `false`
### CheckForSignaturesBeforeRunningScan
Set to: `1`
### DisableRemovableDriveScanning
Indicates whether to scan for malicious and unwanted software in removable drives, such as flash drives, during a full scan
Set to: `true`
### DisableRestorePoint
Indicates whether to disable scanning of restore points
Set to: `true`
### DisableScanningMappedNetworkDrivesForFullScan
Indicates whether to scan mapped network drives
Set to: `true`
### DisableScanningNetworkFiles
Indicates whether to scan for network files
Set to: `false`
### DisableScriptScanning
Specifies whether to disable the scanning of scripts during malware scans
Set to: `false`
### HighThreatDefaultAction
Specifies which automatic remediation action to take for a high level threat
Set to: `Quarantine`
### LowThreatDefaultAction
Specifies which automatic remediation action to take for a low level threat
Set to: `Block`
### ModerateThreatDefaultAction
Specifies which automatic remediation action to take for a moderate level threat
Set to: `Quarantine`
### PUAProtection
Disable PUA Protection
Set to: `Enabled`
### QuarantinePurgeItemsAfterDelay
Specifies the number of days to keep items in the Quarantine folder
Set to: `30`
### RandomizeScheduleTaskTimes
Indicates whether to select a random time for the scheduled start and scheduled update for definitions
Set to: `true`
### RealTimeScanDirection
Specifies scanning configuration for incoming and outgoing files on NTFS volumes
Set to: `0`
### RemediationScheduleDay
Specifies the day of the week on which to perform a scheduled full scan in order to complete remediation
Set to: `Everyday`
### RemediationScheduleTime
Specifies the time of day, as the number of minutes after midnight, to perform a scheduled scan
Set to: `120`
### ReportingAdditionalActionTimeOut
Specifies the number of minutes before a detection in the additional action state changes to the cleared state
Set to: `10080`
### ReportingCriticalFailureTimeOut
Specifies the number of minutes before a detection in the critically failed state changes to either the additional action state or the cleared state
Set to: `10080`
### ReportingNonCriticalTimeOut
Specifies the number of minutes before a detection in the non-critically failed state changes to the cleared state
Set to: `11440`
### ScanAvgCPULoadFactor
Specifies the maximum percentage CPU usage for a scan
Set to: `50`
### ScanOnlyIfIdleEnabled
Indicates whether to start scheduled scans only when the computer is not in use
Set to: `true`
### ScanParameters
Specifies the scan type to use during a scheduled scan
Set to: `1`
### ScanPurgeItemsAfterDelay
Specifies the number of days to keep items in the scan history folder
Set to: `15`
### ScanScheduleDay
Specifies the day of the week on which to perform a scheduled scan
Set to: `Everyday`
### ScanScheduleQuickScanTime
Specifies the time of day, as the number of minutes after midnight, to perform a scheduled quick scan
Set to: `0`
### ScanScheduleTime
Specifies the time of day, as the number of minutes after midnight, to perform a scheduled scan
Set to: `120`
### SevereThreatDefaultAction
Specifies which automatic remediation action to take for a severe level threat
Set to: `Quarantine`
### SignatureAuGracePeriod
Specifies a grace period, in minutes, for the definition
Set to: `0`
### SignatureDisableUpdateOnStartupWithoutEngine
Indicates whether to initiate definition updates even if no antimalware engine is present
Set to: `false`
### SignatureFirstAuGracePeriod
Specifies a grace period, in minutes, for the definition. If a definition successfully updates within this period, Windows Defender abandons any service initiated updates
Set to: `120`
### SignatureScheduleDay
Specifies the day of the week on which to check for definition updates
Set to: `Everyday`
### SignatureScheduleTime
Specifies the time of day, as the number of minutes after midnight, to check for definition updates
Set to: `165`
### SignatureUpdateCatchupInterval
Specifies the number of days after which Windows Defender requires a catch-up definition update
Set to: `1`
### SignatureUpdateInterval
Specifies the interval, in hours, at which to check for definition updates
Set to: `12`
### SubmitSamplesConsent
Specifies how Windows Defender checks for user consent for certain samples
Set to: `AlwaysPrompt`
### MAPSReporting
Membership in Microsoft Active Protection Service Enable
Set to: `Advanced`
### ThrottleLimit
Specifies the maximum number of concurrent operations that can be established to run the cmdlet
Set to: `0`
### UILockdown
Indicates whether to disable UI lock down mode
Set to: `false`
### UnknownThreatDefaultAction
Specifies which automatic remediation action to take for an unknown level threat
Set to: `Block`
### SignatureFallbackOrder
Specifies the order in which to contact different definition update sources. Specify the types of update sources in the order in which you want Windows Defender to contact them, enclosed in braces and separated by the pipeline symbol
Set to: `MicrosoftUpdateServer | MMPC`
### ControlledFolderAccessAllowedApplications
We exclude the following Files by default: `$env:windir\System32\taskhostw.exe`
Any exclusions previously configured stay intact!
### ExclusionPath
The following Files/Folders are excluded from the scan:
`windir\SoftwareDistribution\DataStore\Datastore.edb`
`windir\SoftwareDistribution\DataStore\Logs\Edb*.jrs`
`windir\SoftwareDistribution\DataStore\Logs\Edb.chk`
`windir\SoftwareDistribution\DataStore\Logs\Tmp.edb`
`windir\Security\Database\*.edb`
`windir\Security\Database\*.sdb`
`windir\Security\Database\*.log`
`windir\Security\Database\*.chk`
`windir\Security\Database\*.jrs`
`windir\Security\Database\*.xml`
`windir\Security\Database\*.csv`
`windir\Security\Database\*.cmtx`
`ProgramData\ntuser.pol`
`windir\System32\GroupPolicy\Machine\Registry.pol`
`windir\System32\GroupPolicy\Machine\Registry.tmp`
`windir\System32\GroupPolicy\User\Registry.pol`
`windir\System32\GroupPolicy\User\Registry.tmp`
Any exclusions previously configured stay intact!
More Info: [https://support.microsoft.com/en-us/help/822158/virus-scanning-recommendations-for-enterprise-computers-that-are-runni](https://support.microsoft.com/en-us/help/822158/virus-scanning-recommendations-for-enterprise-computers-that-are-runni)
### ExclusionProcess
The following processes are excluded from the scan:
`$env:windir\System32\svchost.exe`
`$env:windir\System32\wuauclt.exe`
Any exclusions previously configured stay intact!
More Info: [https://support.microsoft.com/en-us/help/822158/virus-scanning-recommendations-for-enterprise-computers-that-are-runni](https://support.microsoft.com/en-us/help/822158/virus-scanning-recommendations-for-enterprise-computers-that-are-runni)
### Process Mitigation and Exploit Protection
Microsoft provides a XML file (`ProcessMitigation.xml`) that provides a configuration best practice to mitigate the attack surface and provide Exploit Protection.
You can provide your own File, otherwise (if missing) we will download the latest version from Microsoft.
More Info: [https://demo.wd.microsoft.com/Page/EP](https://demo.wd.microsoft.com/Page/EP)
### WindowsDefenderSandbox
We tuen on Windows Defender Sandbox
### AttackSurfaceReduction
Attack Surface Reduction (ASR) is comprised of a number of rules, each of which target specific behaviors that are typically used by malware and malicious apps to infect machines, such as:
- Executable files and scripts used in Office apps or web mail that attempt to download or run files
- Scripts that are obfuscated or otherwise suspicious
- Behaviors that apps undertake that are not usually initiated during normal day-to-day work
More Info: [https://demo.wd.microsoft.com/Page/ASR](https://demo.wd.microsoft.com/Page/ASR)
### ReloadRegistry
We then reload the registry to ensure that the new configuration is activated
### EnableFirewall
Enable the Windows Firewall for all Profiles - Set the default to block everything
We enable the Windows Firewall for the following Network-Profiles:
- Domain
- Public
- Private
We block all inbound connections by default and we log all block-events!
### UpdateSignature
As a final touch: We update the Windows Defender signatures.
## Why this?
I use this during the bootstrap process of Windows systems.
Most of the settings here is also enforced by some of our Group Policies and we also have a lot of it configured via MDM CSPs (InTune).
This script is only a quick hack to harden (and secure) any new system, even if it is not managed afterwords.
## Content
There are two files:
### Bootstrap-MicrosoftDefenderConfiguration.ps1
The PowerShell Script itself
### Bootstrap-MicrosoftDefenderConfiguration.csv
A CSV File that contains the configuration of the attack surface reduction rules.
## Configuration
Please review the `Bootstrap-MicrosoftDefenderConfiguration.csv` where you configure the attack surface reduction rules. Please also review the `Bootstrap-MicrosoftDefenderConfiguration.ps1` file. There is no configuration file, at least not yet!
## Further Information
[https://docs.microsoft.com/en-us/powershell/module/defender/index?view=win10-ps](https://docs.microsoft.com/en-us/powershell/module/defender/index?view=win10-ps)
[https://github.com/jhochwald/PowerShell-collection/blob/master/Misc/Optimize-MicrosoftDefenderExclusions.ps1](https://github.com/jhochwald/PowerShell-collection/blob/master/Misc/Optimize-MicrosoftDefenderExclusions.ps1)
[https://docs.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-atp/enable-exploit-protection](https://docs.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-atp/enable-exploit-protection
)
[https://docs.microsoft.com/en-us/powershell/module/defender/set-mppreference?view=win10-ps](https://docs.microsoft.com/en-us/powershell/module/defender/set-mppreference?view=win10-ps)
[https://docs.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-atp/customize-attack-surface-reduction](https://docs.microsoft.com/en-us/powershell/module/defender/set-mppreference?view=win10-ps)
[https://support.microsoft.com/en-us/help/822158/virus-scanning-recommendations-for-enterprise-computers-that-are-runni](https://docs.microsoft.com/en-us/powershell/module/defender/set-mppreference?view=win10-ps)
[https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-antivirus/enable-cloud-protection-windows-defender-antivirus](https://docs.microsoft.com/en-us/powershell/module/defender/set-mppreference?view=win10-ps)
[https://demo.wd.microsoft.com/?ocid=cx-wddocs-testground](https://docs.microsoft.com/en-us/powershell/module/defender/set-mppreference?view=win10-ps)
## License
BSD 3-Clause License
Copyright (c) 2020, Joerg Hochwald
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,158 @@
#requires -Version 3.0 -RunAsAdministrator
<#
.SYNOPSIS
Quick an dirty Windows Service Monitor
.DESCRIPTION
I came across the the problem, that one of the services I depend one was not started after the system reboots.
That happens after a .NET update. So I decided to create this real simple monitor to make sure, that this service is running.
If not, the script tries to restart it.
.PARAMETER MonService
The Service we would like to check. Default is RoyalServer
.EXAMPLE
PS C:\> .\Check-ServiceMonitor.ps1
.EXAMPLE
PS C:\> .\Check-ServiceMonitor.ps1 -MonService 'myservice'
.NOTES
The script itself have some basic error handling,
nothing to complex or fancy.
#>
[CmdletBinding(ConfirmImpact = 'None')]
param
(
[Parameter(ValueFromPipeline,
Position = 1)]
[Alias('ServiceToMonitor')]
[string]
$MonService = 'RoyalServer'
)
begin
{
[string]$SC = 'SilentlyContinue'
[string]$STP = 'Stop'
}
process
{
# Get the Status
try
{
Write-Verbose -Message ('Get the Status of {0}' -f $MonService)
$paramGetService = @{
Name = $MonService
ErrorAction = $STP
WarningAction = $SC
}
[string]$MonServiceStatus = ((Get-Service @paramGetService).Status)
Write-Verbose -Message ('We have the Status of {0}' -f $MonService)
}
catch
{
Write-Error -Message ('Looks like the Service {0} is not installed!' -f $MonService) -ErrorAction $STP
# Point of no return (Should never be reached)
break
}
# Do the check
if ($MonServiceStatus -ne 'Running')
{
Write-Warning -Message ('Sorry, but {0} is not running ' -f $MonService)
try
{
Write-Verbose -Message ('Try to restart {0}' -f $MonService)
$MonParam = @{
Name = $MonService
Confirm = $false
ErrorAction = $STP
WarningAction = $SC
}
$null = (Restart-Service @MonParam)
}
catch
{
# Whooooops! Try it again... Let us try to stop the services
Write-Verbose -Message ('Try to stop {0}' -f $MonService)
$null = (Stop-Service @MonParam)
# Wait a second
$null = (Start-Sleep -Seconds 1)
# Try to stop it again...
$null = (Stop-Service @MonParam)
# Wait a second
$null = (Start-Sleep -Seconds 1)
# Try to kill it, again!
$null = (Stop-Service @MonParam)
# Wait two seconds to cool down
Write-Verbose -Message ('Try to start {0}' -f $MonService)
$null = (Start-Sleep -Seconds 2)
try
{
# Now let us try to start the service
Write-Verbose -Message ('Try to start {0} again!' -f $MonService)
$null = (Start-Service @MonParam)
}
catch
{
# Dude, this is bad! And I mean real bad!!!
Write-Error -Message ('We where not able to start {0} - Might be a good idea to reboot this system' -f $MonService)
}
}
}
else
{
# Looks good so far
Write-Verbose -Message ('Looks like {0} is doing great...' -f $MonService)
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,84 @@
function Clear-EnAllEventLogs
{
<#
.SYNOPSIS
AllEventLlogs
.DESCRIPTION
AllEventLlogs
.PARAMETER ComputerName
Computer Name
.EXAMPLE
PS C:\> Clear-EnAllEventLogs
.NOTES
N.N.
#>
[CmdletBinding(ConfirmImpact = 'Medium',
SupportsShouldProcess)]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[string[]]
$ComputerName = "$env:COMPUTERNAME"
)
process
{
foreach ($SingleComputerName in $ComputerName)
{
if ($pscmdlet.ShouldProcess($SingleComputerName, 'Cleanup All EventLogs'))
{
$paramGetEventLog = @{
ComputerName = $SingleComputerName
List = $true
}
$null = (Get-EventLog @paramGetEventLog | ForEach-Object -Process {
if ($_.Entries)
{
$paramClearEventLog = @{
LogName = $_.Log
Confirm = $false
ErrorAction = 'SilentlyContinue'
}
$null = (Clear-EventLog @paramClearEventLog)
}
})
}
}
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,373 @@
#requires -Version 4.0
<#
.SYNOPSIS
Compare a old and a refactored function to get any Performace differences
.DESCRIPTION
This script compares a simple function (That deletes all Windows Eventlog Entries) with an refacored one.
The request came up during a workshop: I was asked why I use pipes so much and if there is another way, without pipes.
The refactored version was created during the workshop as a prototype.
And to make it easier to compare them, I created this test script.
.EXAMPLE
PS C:\> .\Clear-EnAllEventLogs_TESTS.ps1
.NOTES
Releasenotes:
1.0.0 2019-07-24 Initial Version
THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
Dependencies:
NONE
.LINK
https://www.enatec.io
#>
[CmdletBinding(ConfirmImpact = 'None')]
[OutputType([psobject])]
param ()
#region VersionOfJosh
function Clear-EnAllEventLogs
{
<#
.SYNOPSIS
Delete all Windows event log entries
.DESCRIPTION
Delete all Windows event log entries, without any further interaction.
I use this only after I do some tests on a virtual machine.
Please Note:
It Might be dangerous! It might delete more than you like.
Warning:
All security related will also be removed completely.
If there were any issues, you might never find any information about it!
.PARAMETER ComputerName
Computer Name as String. Multi Value is possible
.EXAMPLE
PS C:\> Clear-EnAllEventLogs
Delete all Windows EventLog Entries on the local Computer.
.EXAMPLE
PS C:\> Clear-EnAllEventLogs -ComputerName FRADC01
Delete all Windows EventLog Entries on the Computer with the name FRADC01.
.EXAMPLE
PS C:\> Clear-EnAllEventLogs -ComputerName 'FRADC01', 'FRADC02'
Delete all Windows EventLog Entries on the Computers with the names FRADC01 and FRADC02.
.NOTES
Releasenotes:
THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
Dependencies:
TNONE
.LINK
https://www.enatec.io
.LINK
about_foreach
.LINK
Foreach-Object
.LINK
Get-EventLog
.LINK
Clear-EventLog
#>
[CmdletBinding(ConfirmImpact = 'Medium',
SupportsShouldProcess)]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[string[]]
$ComputerName = "$env:COMPUTERNAME"
)
process
{
foreach ($SingleComputerName in $ComputerName)
{
if ($pscmdlet.ShouldProcess($SingleComputerName, 'Cleanup All EventLogs'))
{
$paramGetEventLog = @{
ComputerName = $SingleComputerName
List = $true
}
$null = (Get-EventLog @paramGetEventLog | ForEach-Object -Process {
if ($_.Entries)
{
$paramClearEventLog = @{
LogName = $_.Log
Confirm = $false
ErrorAction = 'SilentlyContinue'
}
$null = (Clear-EventLog @paramClearEventLog)
}
})
}
}
}
}
#endregion VersionOfJosh
#region RefactoredVersion
function Clear-EnAllEventLogsv2
{
<#
.SYNOPSIS
Delete all Windows event log entries
.DESCRIPTION
Delete all Windows event log entries, without any further interaction.
I use this only after I do some tests on a virtual machine.
Please Note:
It Might be dangerous! It might delete more than you like.
Warning:
All security related will also be removed completely.
If there were any issues, you might never find any information about it!
.PARAMETER ComputerName
Computer Name as String. Multi Value is possible
.EXAMPLE
PS C:\> Clear-EnAllEventLogsv2
Delete all Windows EventLog Entries on the local Computer.
.EXAMPLE
PS C:\> Clear-EnAllEventLogsv2 -ComputerName FRADC01
Delete all Windows EventLog Entries on the Computer with the name FRADC01.
.EXAMPLE
PS C:\> Clear-EnAllEventLogsv2 -ComputerName 'FRADC01', 'FRADC02'
Delete all Windows EventLog Entries on the Computers with the names FRADC01 and FRADC02.
.NOTES
Releasenotes:
2.0.0 2019-07-23: Refactored version
THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
Dependencies:
NONE
.LINK
https://www.enatec.io
.LINK
about_foreach
.LINK
Foreach-Object
.LINK
Get-EventLog
.LINK
Clear-EventLog
#>
[CmdletBinding(ConfirmImpact = 'Medium',
SupportsShouldProcess)]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[string[]]
$ComputerName = "$env:COMPUTERNAME"
)
process
{
foreach ($SingleComputerName in $ComputerName)
{
if ($pscmdlet.ShouldProcess($SingleComputerName, 'Cleanup All EventLogs'))
{
$paramGetEventLog = @{
ComputerName = $SingleComputerName
List = $true
}
$null = ((Get-EventLog @paramGetEventLog).Where( {
if ($_.Entries)
{
$_
}
}).ForEach( {
$paramClearEventLog = @{
LogName = $_.Log
Confirm = $false
ErrorAction = 'SilentlyContinue'
}
$null = (Clear-EventLog @paramClearEventLog)
}))
}
}
}
}
#endregion RefactoredVersion
#region CreateTestData
function Invoke-CreateTestData
{
<#
.SYNOPSIS
Create 10.000 dummy entries
.DESCRIPTION
Create 10.000 dummy entries
.EXAMPLE
PS C:\> Invoke-CreateTestData
.NOTES
Internal Helper Function to create some useless Test Data
Releasenotes:
1.0.1 2019-07-23: Splat the parameters for better radability
1.0.0 2019-07-23: Initial Version
THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
Dependencies:
NONE
.LINK
https://www.enatec.io
.LINK
Write-EventLog
.LINK
about_foreach
.LINK
Foreach-Object
#>
[CmdletBinding(ConfirmImpact = 'None')]
param ()
begin
{
# Splat the parameters
$paramWriteEventLog = @{
LogName = 'Application'
EventId = 2001
EntryType = 'Information'
Source = 'HAL9000'
Message = 'I think you know what the problem is just as well as I do.'
ErrorAction = 'SilentlyContinue'
}
}
process
{
# Change the number to fit your needs
1 .. 1000 | ForEach-Object -Process {
$null = (Write-EventLog @paramWriteEventLog)
}
}
}
#endregion CreateTestData
# Initial Cleanup
$null = (Clear-EnAllEventLogs -ErrorAction SilentlyContinue)
# Create a few new objects
$OldWayAverage = @()
$OldWaySum = @()
$NewWayAverage = @()
$NewWaySum = @()
# Create the new Eventlog
$null = (New-EventLog -LogName Application -Source 'HAL9000' -ErrorAction SilentlyContinue)
#region OldWay
$null = (1..10 | ForEach-Object {
# Create some Test Data
$null = (Invoke-CreateTestData -ErrorAction SilentlyContinue)
#region OldWaySingle
$OldWaySingle = (Measure-Command -Expression {
$null = (Clear-EnAllEventLogs -ErrorAction SilentlyContinue)
})
#endregion OldWaySingle
$OldWaySum += $OldWaySingle
})
$OldWayAverage = (($OldWaySum | Measure-Object -Property TotalMilliseconds -Average).Average)
#endregion OldWay
#region NewWay
$null = (1..10 | ForEach-Object {
# Create some Test Data
$null = (Invoke-CreateTestData -ErrorAction SilentlyContinue)
#region NewWaySingle
$NewWaySingle = (Measure-Command -Expression {
$null = (Clear-EnAllEventLogsv2 -ErrorAction SilentlyContinue)
})
#endregion NewWaySingle
$NewWaySum += $NewWaySingle
})
$NewWayAverage = (($NewWaySum | Measure-Object -Property TotalMilliseconds -Average).Average)
#endregion NewWay
#Region DumpData
Write-Verbose -Message 'Time measured in milliseconds' -Verbose
[pscustomobject]@{
OldWay = $OldWayAverage
NewWay = $NewWayAverage
}
#endregion DumpData
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,85 @@
function Clear-EnAllEventLogsv2
{
<#
.SYNOPSIS
AllEventLlogs
.DESCRIPTION
AllEventLlogs
.PARAMETER ComputerName
Computer Name
.EXAMPLE
PS C:\> Clear-EnAllEventLogsv2
.NOTES
N.N.
#>
[CmdletBinding(ConfirmImpact = 'Medium',
SupportsShouldProcess)]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[string[]]
$ComputerName = "$env:COMPUTERNAME"
)
process
{
foreach ($SingleComputerName in $ComputerName)
{
if ($pscmdlet.ShouldProcess($SingleComputerName, 'Cleanup All EventLogs'))
{
$paramGetEventLog = @{
ComputerName = $SingleComputerName
List = $true
}
$null = ((Get-EventLog @paramGetEventLog).Where( {
if ($_.Entries)
{
$_
}
}).ForEach( {
$paramClearEventLog = @{
LogName = $_.Log
Confirm = $false
ErrorAction = 'SilentlyContinue'
}
$null = (Clear-EventLog @paramClearEventLog)
}))
}
}
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,6 @@
# Disable the .NET Telemetry on production servers and critical workstations
[Environment]::SetEnvironmentVariable('DOTNET_CLI_TELEMETRY_OPTOUT', '1', 'Machine')
[Environment]::SetEnvironmentVariable('MLDOTNET_CLI_TELEMETRY_OPTOUT', '1', 'Machine')
# Tweak the 1st run experience
[Environment]::SetEnvironmentVariable('DOTNET_SKIP_FIRST_TIME_EXPERIENCE', '1', 'Machine')

View File

@@ -0,0 +1,272 @@
#requires -Version 3.0 -Modules CimCmdlets, DnsClient, NetAdapter, NetTCPIP -RunAsAdministrator
<#
.SYNOPSIS
Enable DNS-over-HTTPS (DoH) if device is not domain-joined
.DESCRIPTION
Enable DNS-over-HTTPS (DoH) if device is not domain-joined
It enables the Cloudflare DNS Servers, even if DoH is not working yet.
IPv6 Support is optional.
.PARAMETER IPv6
Enable IPv6 Support, IPv6 Servers will be added to the serverlist
.EXAMPLE
PS C:\> .\Enable-DNSOverHTTPS.ps1
Enable DNS-over-HTTPS (DoH) if device is not domain-joined for IPv4 only
.EXAMPLE
PS C:\> .\Enable-DNSOverHTTPS.ps1 -IPv6
Enable DNS-over-HTTPS (DoH) if device is not domain-joined for IPv4 and IPv6
.NOTES
Only the Insider Build of Windows 10 supports DoH!
But we configure it anyway!
The Cloudflare servers are used for regular DNS resolution and as soon as DoH is supported,
we can configure and use it anyway.
A future version of this script might support additional parameters, like DohFlags
You can also change the servers below to any service you like, e.g. Google DNS or Quad9 from IBM.
The Bool as return was requested by a customer, and the exit code (0 or 1) is implemented for our bootstrap setup
.LINK
https://1.1.1.1/dns/
.LINK
https://techcommunity.microsoft.com/t5/networking-blog/windows-insiders-can-now-test-dns-over-https/ba-p/1381282
#>
[CmdletBinding(ConfirmImpact = 'None')]
[OutputType([bool])]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[Alias('IP6', '6')]
[switch]
$IPv6
)
begin
{
#region Defaults
$SCT = 'SilentlyContinue'
$STP = 'Stop'
$CNT = 'Continue'
# Save the infos from the switches
if (($PSCmdlet.MyInvocation.BoundParameters['Verbose']).IsPresent)
{
$IsVerbose = $true
}
else
{
$IsVerbose = $false
}
if (($PSCmdlet.MyInvocation.BoundParameters['Debug']).IsPresent)
{
$IsDebug = $true
}
else
{
$IsDebug = $false
}
if (($PSCmdlet.MyInvocation.BoundParameters['WhatIf']).IsPresent)
{
$IsWhatIf = $true
}
else
{
$IsWhatIf = $false
}
#endregion Defaults
#region ServerAddresses
# Create an Empty Object
$ServerAddresses = @()
# IPv4 DNS Servers to use
$ServerAddressesIPv4 = @(
'1.1.1.1'
'1.0.0.1'
)
# Add the IPv4 Servers to the Object
$ServerAddresses += $ServerAddressesIPv4
if ((($PSCmdlet.MyInvocation.BoundParameters['IPv6']).IsPresent) -eq $true)
{
Write-Verbose -Message 'IPv6 Servers will be added to the serverlist'
# IPv6 DNS Servers to use
$ServerAddressesIPv6 = @(
'2606:4700:4700::1111'
'2606:4700:4700::1001'
)
# Add the IPv6 Servers to the Object
$ServerAddresses += $ServerAddressesIPv6
}
#endregion ServerAddresses
}
process
{
#region DoH
# Enable DNS-over-HTTPS for IPv4 if device is not domain-joined
$paramGetCimInstance = @{
ClassName = 'CIM_ComputerSystem'
Verbose = $IsVerbose
Debug = $IsDebug
ErrorAction = $STP
}
if (((Get-CimInstance @paramGetCimInstance).PartOfDomain) -eq $false)
{
try
{
# Temporarily key
$paramNewItemProperty = @{
Path = 'HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters'
Name = 'EnableAutoDoh'
Value = 2
PropertyType = 'DWord'
Force = $true
WhatIf = $IsWhatIf
Verbose = $IsVerbose
Debug = $IsDebug
ErrorAction = $CNT
}
$null = (New-ItemProperty @paramNewItemProperty)
$paramGetNetAdapter = @{
Verbose = $IsVerbose
Debug = $IsDebug
Physical = $true
ErrorAction = $SCT
}
$MACAddress = ((Get-NetAdapter @paramGetNetAdapter).MacAddress)
$paramGetNetIPConfiguration = @{
Verbose = $IsVerbose
Debug = $IsDebug
ErrorAction = $SCT
}
$IpConfig = (Get-NetIPConfiguration @paramGetNetIPConfiguration | Where-Object -FilterScript {
$MACAddress -eq $_.NetAdapter.MacAddress
})
$paramSetDnsClientServerAddress = @{
ServerAddresses = $ServerAddresses
Verbose = $IsVerbose
Debug = $IsDebug
ErrorAction = $CNT
}
$null = ($IpConfig | Set-DnsClientServerAddress @paramSetDnsClientServerAddress)
$paramClearDnsClientCache = @{
Verbose = $IsVerbose
Debug = $IsDebug
ErrorAction = $SCT
}
$null = (Clear-DnsClientCache @paramClearDnsClientCache)
$paramRegisterDnsClient = @{
Verbose = $IsVerbose
Debug = $IsDebug
ErrorAction = $SCT
}
$null = (Register-DnsClient @paramRegisterDnsClient)
}
catch
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
$paramWriteError = @{
Message = $e.Exception.Message
ErrorAction = $CNT
Exception = $e.Exception
TargetObject = $e.CategoryInfo.TargetName
}
Write-Error @paramWriteError
}
}
else
{
$paramWriteError = @{
Message = 'Sorry, this computer seems to be part of a Active Directory domain!'
Exception = 'Active Directory Domain Members are not supported'
Category = 'NotEnabled'
TargetObject = $env:COMPUTERNAME
ErrorAction = $CNT
}
Write-Error @paramWriteError
# Return the Bool
Write-Output -InputObject $false
# Unclean exit
exit 1
}
#endregion DoH
}
end
{
# Return the Bool
Write-Output -InputObject $true
# Clean exit
exit 0
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,56 @@
#requires -RunAsAdministrator
<#
.SYNOPSIS
Force Time re-sync with PowerShell
.DESCRIPTION
Force Time re-sync as a PowerShell script
.EXAMPLE
PS C:\> .\ForceTimeResync.ps1
Force Time Resync as a PowerShell script (Wrapper for w32tm.exe). Most be executed in an elevated shell)
.NOTES
One of my VM's did a view time travels in the past. This little script runs every hour (Task).
I still try to find the cause for the time travels (It jumps 2 hours forward, from time to time) and a better PowerShell way to do it.
For now, this quick and dirty solution works just fine.
#>
[CmdletBinding(ConfirmImpact = 'None')]
param ()
process
{
$null = (& "$env:windir\system32\w32tm.exe" /resync /force)
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,114 @@
function Get-AllCookiesFromWebRequestSession
{
<#
.SYNOPSIS
Get all cookies stored in the WebRequestSession variable from any Invoke-RestMethod and/or Invoke-WebRequest request
.DESCRIPTION
Get all cookies stored in the WebRequestSession variable from any Invoke-RestMethod and/or Invoke-WebRequest request
The WebRequestSession stores useful info and it has something that some my know as CookieJar or http.cookiejar.
.PARAMETER WebRequestSession
Specifies a variable where Invoke-RestMethod and/or Invoke-WebRequest saves values.
Must be a valid [Microsoft.PowerShell.Commands.WebRequestSession] object!
.EXAMPLE
PS C:\> $null = Invoke-WebRequest -UseBasicParsing -Uri 'http://jhochwald.com' -Method Get -SessionVariable WebSession -ErrorAction SilentlyContinue
PS C:\> $WebSession | Get-AllCookiesFromWebRequestSession
Get all cookies stored in the $WebSession variable from the request above.
This page doesn't use or set any cookies, but the (awesome) CloudFlare service does.
.EXAMPLE
$null = Invoke-RestMethod -UseBasicParsing -Uri 'https://jsonplaceholder.typicode.com/todos/1' -Method Get -SessionVariable RestSession -ErrorAction SilentlyContinue
$RestSession | Get-AllCookiesFromWebRequestSession
Get all cookies stored in the $RestSession variable from the request above.
Please do not abuse the free API service above!
.NOTES
I used something I had stolen from Chrissy LeMaire's TechNet Gallery entry a (very) long time ago.
But I needed something more generic, independent from the URL! This can become handy, to find any cookie from a 3rd party site or another host.
.LINK
https://docs.python.org/3/library/http.cookiejar.html
.LINK
https://en.wikipedia.org/wiki/HTTP_cookie
.LINK
https://gallery.technet.microsoft.com/scriptcenter/Getting-Cookies-using-3c373c7e
.LINK
Invoke-RestMethod
.LINK
Invoke-WebRequest
#>
[CmdletBinding(ConfirmImpact = 'None')]
param
(
[Parameter(Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 0,
HelpMessage = 'Specifies a variable where Invoke-RestMethod and/or Invoke-WebRequest saves values.')]
[ValidateNotNull()]
[Alias('Session', 'InputObject')]
[Microsoft.PowerShell.Commands.WebRequestSession]
$WebRequestSession
)
begin
{
# Do the housekeeping
$CookieInfoObject = $null
}
process
{
try
{
# I know, this look very crappy, but it just work fine!
[pscustomobject]$CookieInfoObject = ((($WebRequestSession).Cookies).GetType().InvokeMember('m_domainTable', [Reflection.BindingFlags]::NonPublic -bor [Reflection.BindingFlags]::GetField -bor [Reflection.BindingFlags]::Instance, $null, (($WebRequestSession).Cookies), @()))
}
catch
{
#region ErrorHandler
# get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
$paramWriteError = @{
Message = $e.Exception.Message
ErrorAction = 'Stop'
Exception = $e.Exception
TargetObject = $e.CategoryInfo.TargetName
}
Write-Error @paramWriteError
# Only here to catch a global ErrorAction overwrite
exit 1
#endregion ErrorHandler
}
}
end
{
# Dump the Cookies to the Console
((($CookieInfoObject).Values).Values)
}
}

View File

@@ -0,0 +1,134 @@
function Get-DirectorySize
{
<#
.SYNOPSIS
Get the size of a given folder in a human readable format
.DESCRIPTION
Get the size of a given folder in a human readable format
.PARAMETER Path
Folder to check
.PARAMETER Type
Type of the Return,
Valid values are: GB, MB, KB, B
The default is MB (Megabyte)
.EXAMPLE
PS C:\> Get-DirectorySize -Path 'C:\scripts'
.EXAMPLE
PS C:\> Get-DirectorySize -Path 'C:\scripts' -Type GB
.NOTES
PowerShell function to emulate the wel known Linux DU command
Releasenotes:
1.0.0 2019-05-09: Initial Release
THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
#>
[CmdletBinding(ConfirmImpact = 'None')]
[OutputType([string])]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
[Alias('Directory', 'Folder')]
[string]
$Path = '.',
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
[ValidateSet('GB', 'MB', 'KB', 'B', IgnoreCase = $true)]
[Alias('InType')]
[string]
$Type = 'MB'
)
process
{
try
{
$AllFolderItems = (Get-ChildItem -Path $Path -Recurse -ErrorAction Stop | Measure-Object -Property length -Sum)
switch ($Type)
{
'GB'
{
$FolderSize = '{0:N2}' -f ($AllFolderItems.sum / 1GB) + ' GB'
}
'MB'
{
$FolderSize = '{0:N2}' -f ($AllFolderItems.sum / 1MB) + ' MB'
}
'KB'
{
$FolderSize = '{0:N2}' -f ($AllFolderItems.sum / 1KB) + ' KB'
}
'B'
{
$FolderSize = '{0:N2}' -f ($AllFolderItems.sum) + ' B'
}
Default
{
$FolderSize = '{0:N2}' -f ($AllFolderItems.sum) + ' MB'
}
}
return $FolderSize
}
catch
{
# get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
Write-Error -Message $e.Exception.Message -ErrorAction Continue -Exception $e.Exception -TargetObject $e.CategoryInfo.TargetName
}
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,463 @@
function Get-FritzBoxEvents
{
<#
.SYNOPSIS
Get the Events from a FritzBox router
.DESCRIPTION
Get the Events from a FritzBox router
.PARAMETER FritzBoxUser
Username to use for the FritzBox login
.PARAMETER FritzBoxPassword
FritzBox Password in plain text (might be changed to a secure string soon)
.PARAMETER FritzBoxHost
The URI that contains the FQDN or IP of your FritzBox,
e.g. http://fritz.box or http://192.168.178.1
.PARAMETER Hours
Hours to get, e.g. 24
.EXAMPLE
PS C:\> Get-FritzBoxEvents -FritzBoxUser 'myFritz' -FritzBoxPassword 'ThePassw0rd' -FritzBoxHost 'http://myfritz.box' -Hours 24 | Where-Object {(($_.ipv4 -ne $null) -or ($_.ipv6 -ne $null))}
Get only entries with IPv4 or IPv6 values, of the last 24 hours
.EXAMPLE
PS C:\> Get-FritzBoxEvents -FritzBoxUser 'myFritz' -FritzBoxPassword 'ThePassw0rd' -FritzBoxHost 'http://myfritz.box' -Hours 48 | Where-Object {($_.ipv6 -ne $null)}
Get only entries with IPv6 values, of the last 48 hours
.EXAMPLE
PS C:\> Get-FritzBoxEvents -FritzBoxUser 'myFritz' -FritzBoxPassword 'ThePassw0rd' -FritzBoxHost 'http://myfritz.box' | Where-Object {($_.Message -like 'Die Systemzeit wurde erfolgreich aktualisiert von Zeitserver*')}
Get all events where the time was set via a time server, no time limit
.EXAMPLE
PS C:\> Get-FritzBoxEvents -FritzBoxUser 'myFritz' -FritzBoxPassword 'ThePassw0rd' -FritzBoxHost 'http://myfritz.box' | Where-Object {($_.Message -like 'Die Systemzeit wurde erfolgreich aktualisiert von Zeitserver*')} | Select-Object -ExpandProperty IPv4
Get all events where the time was set via a time server, only return the IPv4 addresses, no time limit
.EXAMPLE
PS C:\> ((Get-FritzBoxEvents -FritzBoxUser 'myFritz' -FritzBoxPassword 'ThePassw0rd' -FritzBoxHost 'http://myfritz.box' | Where-Object {($_.Message -like 'Die Systemzeit wurde erfolgreich aktualisiert von Zeitserver*')})[0] | Select-Object -ExpandProperty IPv4)
Get all events where the time was set via a time server, only return the IPv4 address of the latest (youngest) event
.EXAMPLE
PS C:\> Get-FritzBoxEvents -FritzBoxUser 'myFritz' -FritzBoxPassword 'ThePassw0rd' -FritzBoxHost 'http://myfritz.box' | Where-Object {($_.Message -like '*main-repeater*')}
Only return events from a repeater with the name main-repeater, no time limit
.EXAMPLE
PS C:\> (Get-FritzBoxEvents -FritzBoxUser 'myFritz' -FritzBoxPassword 'ThePassw0rd' -FritzBoxHost 'http://myfritz.box' | Where-Object {($_.Message -like '*main-repeater*')})[0]
Only return the latest (youngest) events from a repeater with the name main-repeater, no time limit
.EXAMPLE
PS C:\> Get-FritzBoxEvents -FritzBoxUser 'myFritz' -FritzBoxPassword 'ThePassw0rd' -FritzBoxHost 'http://myfritz.box' | Where-Object {($_.Message -like '*Zeitserver * antwortet nicht.')}
Only return events where the Timeserver does NOT answer, no time limit
.EXAMPLE
PS C:\> Get-FritzBoxEvents -FritzBoxUser 'myFritz' -FritzBoxPassword 'ThePassw0rd' -FritzBoxHost 'http://myfritz.box' | Where-Object {($_.Message -like '*verschlüsselten DNS-Servern*')}
All events related to encrypted DNS, no time limit
.EXAMPLE
PS C:\> Get-FritzBoxEvents -FritzBoxUser 'myFritz' -FritzBoxPassword 'ThePassw0rd' -FritzBoxHost 'http://myfritz.box' -Hours 24 | Where-Object {($_.Message -like '*Authentifizierungsfehler*')}
Only events with authentication errors, of the last 24 hours
.EXAMPLE
PS C:\> ((Get-FritzBoxEvents -FritzBoxUser 'myFritz' -FritzBoxPassword 'ThePassw0rd' -FritzBoxHost 'http://myfritz.box' | Where-Object {($_.Message -like '*(verfügbare Bitrate)*')})[0] | Select-Object -ExpandProperty Message)
The latest (youngest) event that has the bitrate info (capacity)
.EXAMPLE
PS C:\> ((Get-FritzBoxEvents -FritzBoxUser 'myFritz' -FritzBoxPassword 'ThePassw0rd' -FritzBoxHost 'http://myfritz.box' | Where-Object {($_.Message -like 'Internetverbindung wurde erfolgreich hergestellt.*')})[0] | Select-Object -ExpandProperty IPv4)
Get the public IPv4 address
.EXAMPLE
PS C:\> ((Get-FritzBoxEvents -FritzBoxUser 'myFritz' -FritzBoxPassword 'ThePassw0rd' -FritzBoxHost 'http://myfritz.box' | Where-Object {($_.Message -like 'Internetverbindung IPv6 wurde erfolgreich hergestellt.*')})[0] | Select-Object -ExpandProperty IPv6)
Get the public IPv6 address
.EXAMPLE
PS C:\> ((Get-FritzBoxEvents -FritzBoxUser 'myFritz' -FritzBoxPassword 'ThePassw0rd' -FritzBoxHost 'http://myfritz.box' | Where-Object {(($_.Message -like '*IPv6-Präfix wurde erfolgreich bezogen.*') -and ($_.ipv6 -ne $null))})[0] | Select-Object -ExpandProperty IPv6)
Get the latest public IPv6 prefix (CIDR)
.EXAMPLE
PS C:\> ((Get-FritzBoxEvents -FritzBoxUser 'myFritz' -FritzBoxPassword 'ThePassw0rd' -FritzBoxHost 'http://myfritz.box' | Where-Object {(($_.Message -like 'Freigabe als Exposed Host auf * (*) hinzugefügt.') -and ($_.ipv4 -ne $null))})[0] | Select-Object -ExpandProperty IPv4)
get the exposed host IPv4
.EXAMPLE
PS C:\> $IPv6TMP = (Get-FritzBoxEvents -FritzBoxUser 'myFritz' -FritzBoxPassword 'ThePassw0rd' -FritzBoxHost 'http://myfritz.box' | Where-Object {(($_.Message -like 'Freigabe als Exposed Host auf * (*) hinzugefügt.') -and ($_.ipv4 -eq $null))} | Select-Object -ExpandProperty Message)
PS C:\> $regex = [regex]'(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))'
PS C:\> $regex.Matches($IPv6TMP) | ForEach-Object{ $_.value }
Get the exposed host IPv6 address and/or IPv6 CIDR (of exists)
.LINK
https://github.com/jangeisbauer/FritzBox2Sentinel
.LINK
https://gist.github.com/joasch/e48738417ec1efcc963a96bbb3f34cba
.LINK
https://www.ip-phone-forum.de/threads/ereignisprotokoll-der-fritz-box-auf-linux-server-sichern.280328/page-5
.NOTES
All tests in the examples are only valid if your FritzBox has a german UI!
For other languages, dump all events and search for the matches in your own language
If you have issues with german umlauts, use the following before stating the command:
[console]::OutputEncoding = [System.Text.Encoding]::GetEncoding(1252)
I had issues on macOS and Linux with german umlauts, never happened on Windows!
Idea is stolen from https://github.com/jangeisbauer/FritzBox2Sentinel (No license was applied)
So, @jangeisbauer is considered as a contributor
#>
[CmdletBinding(ConfirmImpact = 'None')]
[OutputType([array])]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[ValidateNotNull()]
[ValidateNotNullOrEmpty()]
[Alias('FBUser', 'user')]
[string]
$FritzBoxUser = $null,
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[ValidateNotNull()]
[ValidateNotNullOrEmpty()]
[Alias('Password', 'fbpassword')]
[string]
$FritzBoxPassword = $null,
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[ValidateNotNull()]
[ValidateNotNullOrEmpty()]
[Alias('fbhost', 'host', 'fritzbox')]
[string]
$FritzBoxHost = 'http://fritz.box',
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[int]
$Hours = $null
)
begin
{
# Garbage Collection
[GC]::Collect()
#region Helper
function Get-MD5Hash
{
<#
.SYNOPSIS
Return a MD5 hash of a given String
.DESCRIPTION
Return a MD5 hash of a given String
.PARAMETER Text
String to convert
.EXAMPLE
PS C:\> Get-MD5Hash -Text 'Value1'
.LINK
https://github.com/jangeisbauer/FritzBox2Sentinel
.NOTES
Cheap internal helper
Stolen from https://github.com/jangeisbauer/FritzBox2Sentinel (No license was applied)
#>
[CmdletBinding(ConfirmImpact = 'None')]
[OutputType([string])]
param
(
[Parameter(Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
HelpMessage = 'String to convert')]
[ValidateNotNull()]
[ValidateNotNullOrEmpty()]
[string]
$Text
)
begin
{
$md5 = (New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider)
}
process
{
$md5.ComputeHash([Text.Encoding]::utf8.getbytes($Text)) | ForEach-Object -Process {
$HC = ''
} {
$HC += $_.tostring('x2')
} {
$HC
}
}
}
#endregion Helper
}
process
{
try
{
# Convert the plain text password to a secure string
$FritzBoxSecurePassword = ($FritzBoxPassword | ConvertTo-SecureString -AsPlainText -Force -ErrorAction Stop)
# FritzBox Pages to get
$FritzBoxLoginPage = '/login_sid.lua'
$FritzBoxEventPage = '/query.lua?mq_log=logger:status/log&sid='
# Secret handler
$SecureStringToBSTR = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($FritzBoxSecurePassword)
$PtrToStringAuto = [Runtime.InteropServices.Marshal]::PtrToStringBSTR($SecureStringToBSTR)
# Get the challenge from the FritzBox Login Page
$ChallengeRequest = (Invoke-WebRequest -Uri ($FritzBoxHost + $FritzBoxLoginPage) -UseBasicParsing -ErrorAction Stop)
# Save the recived challenge
$Challenge = ([xml]$ChallengeRequest).sessioninfo.challenge
# Create the input for the HEX code
$Code1 = ($Challenge + '-' + $PtrToStringAuto)
# Create the HEX data string
$Code2 = ([char[]]$Code1 | ForEach-Object -Process {
$Code2 = ''
} {
$Code2 += $_ + [Char]0
} {
$Code2
})
# Create the body part for the next request (includes the MD5 hash of the HEX from above)
$SIDRequestBody = ('response=' + $Challenge + '-' + $(Get-MD5Hash -text ($Code2)) + '&username=' + $FritzBoxUser)
# Do the real Login
$SIDRequest = (Invoke-WebRequest -Uri ($FritzBoxHost + $FritzBoxLoginPage) -Method Post -Body $SIDRequestBody -ErrorAction Stop)
# Extract the SID from the Login request
$SID = ((([xml]($SIDRequest.Content)).ChildNodes).sid)
# Get the Events
$FritzBoxEvents = (Invoke-WebRequest -Uri ($FritzBoxHost + $FritzBoxEventPage + $SID) -UseBasicParsing -ErrorAction Stop)
# Do we have a time limit?
if ($Hours -ne 0)
{
# Create a filter
$Filterhours = ((Get-Date).AddHours(-$Hours))
}
else
{
# No filter needed
$Filterhours = $null
}
# Create a new Array
$FritzEvents = @()
# loop over the events we have (and extract the JSON return that contains all events)
foreach ($FritzBoxEvent in ($FritzBoxEvents.Content | ConvertFrom-Json -ErrorAction Stop).mq_log)
{
try
{
# Cleanup
$EventDate = $null
$IPv6 = $null
$IPv4 = $null
$EventEntry = $null
# Transform the Data
$EventDate = [regex]::Matches($FritzBoxEvent, '\d\d\.\d\d\.\d\d \d\d:\d\d:\d\d')[0].Value
# This REGEX should match IPv6 and IPv6 CIDR
$IPv6 = [regex]::Matches($FritzBoxEvent[0], '((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$')[0].Value
# Simple IPv4 REGEX
$IPv4 = [regex]::Matches($FritzBoxEvent[0], '(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)')[0].Value
# Do we have a DATE in the event?
if ($EventDate -ne '')
{
# Transform the Event DATE
$EventEntry = $FritzBoxEvent[0].replace($EventDate, '')
# Ensure we have the correct format, just in case
#$EventDate = (Get-Date -Date $EventDate)
}
# Apply the Limit, if needed
if (($Filterhours) -and ($EventDate -ge $Filterhours))
{
# Cleanup the event message (remove leading or trailing whitespaces)
$EventEntry = $EventEntry.trim()
# Add the Event to the list
$FritzEvents += [PSCustomObject]@{
Date = $EventDate
Message = $EventEntry
IPv4 = $IPv4
IPv6 = $IPv6
}
}
# Cleanup
$EventDate = $null
$IPv6 = $null
$IPv4 = $null
$EventEntry = $null
}
catch
{
#region ErrorHandler
# get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
Write-Warning -Message $e.Exception.Message -WarningAction Continue
#endregion ErrorHandler
}
}
}
catch
{
# Cleanup
$FritzEvents = $null
$FritzBoxSecurePassword = $null
$FritzBoxLoginPage = $null
$FritzBoxEventPage = $null
$SecureStringToBSTR = $null
$PtrToStringAuto = $null
$ChallengeRequest = $null
$Challenge = $null
$Code1 = $null
$Code2 = $null
$SIDRequestBody = $null
$SIDRequest = $null
$SID = $null
$FritzBoxEvents = $null
$Hours = $null
$Filterhours = $null
#region ErrorHandler
# get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
$paramWriteError = @{
Message = $e.Exception.Message
ErrorAction = 'Stop'
Exception = $e.Exception
TargetObject = $e.CategoryInfo.TargetName
}
Write-Error @paramWriteError
# Only here to catch a global ErrorAction overwrite
exit 1
#endregion ErrorHandler
}
finally
{
# Garbage Collection
[GC]::Collect()
}
}
end
{
# Dump to the Terminal
$FritzEvents
# Cleanup
$FritzEvents = $null
$FritzBoxSecurePassword = $null
$FritzBoxLoginPage = $null
$FritzBoxEventPage = $null
$SecureStringToBSTR = $null
$PtrToStringAuto = $null
$ChallengeRequest = $null
$Challenge = $null
$Code1 = $null
$Code2 = $null
$SIDRequestBody = $null
$SIDRequest = $null
$SID = $null
$FritzBoxEvents = $null
$Hours = $null
$Filterhours = $null
# Garbage Collection
[GC]::Collect()
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,188 @@
function Get-IPv6InWindows
{
<#
.SYNOPSIS
Get the configured IPv6 value from the registry
.DESCRIPTION
Get the configured IPv6 value from the registry
Transforms the Registry value into human understandable values
.EXAMPLE
PS C:\> Get-IPv6InWindows
All IPv6 components are enabled (0)
.EXAMPLE
PS C:\> Get-IPv6InWindows -verbose
Prefer IPv4 over IPv6 (32)
Get the configured IPv6 value from the registry, with verbose output
.LINK
Set-IPv6InWindows
.LINK
https://docs.microsoft.com/en-us/troubleshoot/windows-server/networking/configure-ipv6-in-windows
.LINK
https://docs.microsoft.com/en-us/troubleshoot/windows-server/networking/configure-ipv6-in-windows#reference
.NOTES
Just a wrapper to make the values more human readable.
This is just a quick and dirty initial version!
If you find any further values (other then the supported), please let me know!
Want to modify your IPv6 configuration? Use its companion Set-IPv6InWindows
#>
[CmdletBinding(ConfirmImpact = 'None')]
[OutputType([string])]
param ()
begin
{
# Cleanup
$ComponentValue = $null
$ComponentValueText = $null
#region BoundParameters
if (($PSCmdlet.MyInvocation.BoundParameters['Verbose']).IsPresent)
{
$IsVerbose = $true
}
else
{
$IsVerbose = $false
}
if (($PSCmdlet.MyInvocation.BoundParameters['Debug']).IsPresent)
{
$IsDebug = $true
}
else
{
$IsDebug = $false
}
#endregion BoundParameters
}
process
{
# Get the Value from the registry
try
{
$paramGetItemProperty = @{
Path = 'HKLM:\SYSTEM\CurrentControlSet\Services\tcpip6\Parameters'
Name = 'DisabledComponents'
Debug = $IsDebug
Verbose = $IsVerbose
ErrorAction = 'Stop'
WarningAction = 'Continue'
}
$ComponentValue = (Get-ItemProperty @paramGetItemProperty | Select-Object -ExpandProperty DisabledComponents -ErrorAction Stop -WarningAction Continue)
}
catch
{
#region ErrorHandler
# get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
Write-Verbose -Message $info
Write-Error -Message ($info.Exception) -ErrorAction Stop
# Only here to catch a global ErrorAction overwrite
exit 1
#endregion ErrorHandler
}
switch ($ComponentValue)
{
0
{
$ComponentValueText = ('All IPv6 components are enabled ({0})' -f $ComponentValue)
}
255
{
$ComponentValueText = ('All IPv6 components are disabled ({0})' -f $ComponentValue)
}
2
{
$ComponentValueText = ('6to4 is disabled ({0})' -f $ComponentValue)
}
4
{
$ComponentValueText = ('ISATAP is disabled ({0})' -f $ComponentValue)
}
8
{
$ComponentValueText = ('Teredo is disabled ({0})' -f $ComponentValue)
}
10
{
$ComponentValueText = ('Teredo and 6to4 is disabled ({0})' -f $ComponentValue)
}
1
{
$ComponentValueText = ('All tunnel interfaces are disabled ({0})' -f $ComponentValue)
}
16
{
$ComponentValueText = ('All LAN and PPP interfaces are disabled ({0})' -f $ComponentValue)
}
17
{
$ComponentValueText = ('All LAN, PPP and tunnel interfaces are disabled ({0})' -f $ComponentValue)
}
32
{
$ComponentValueText = ('Prefer IPv4 over IPv6 ({0})' -f $ComponentValue)
}
default
{
$ComponentValueText = ('Unknown value found: {0}' -f $ComponentValue)
}
}
}
end
{
# Dump the info
$ComponentValueText
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,75 @@
<#
.SYNOPSIS
Get all local IP addresses
.DESCRIPTION
Get all local IP addresses, just the addresses
.EXAMPLE
PS C:\> .\Get-IpInfo.ps1
Get all local IP addresses, just the addresses
.NOTES
Quick an dirty function that uses Net.DNS to gather the information about the IP Addresses
#>
[CmdletBinding(ConfirmImpact = 'None')]
[OutputType([psobject])]
param ()
begin
{
#Cleanup
$IpAddressInfo = $null
}
process
{
# Get the Info using Net.Dns
$IpAddressInfo = @(
(([Net.DNS]::GetHostAddresses([Net.Dns]::GetHostByName(($env:COMPUTERNAME)).HostName) | Where-Object -FilterScript {
$_.IsIPv6LinkLocal -eq $false
}).IPAddressToString | Where-Object -FilterScript {
$_ -ne '::1'
})
)
}
end
{
# Dump the Info
$IpAddressInfo
#Cleanup
$IpAddressInfo = $null
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,106 @@
function Get-LocalGroupMembership
{
<#
.SYNOPSIS
Get all local Groups a given User is a Member of
.DESCRIPTION
The the the membership of all local Groups for a given User.
The Given User could be a local User (COMPUTER\USER) or a Domain User (DOMAIN\USER).
.PARAMETER UserName
Given User could be a local User (COMPUTER\USER) or a Domain User (DOMAIN\USER).
Default is the user that executes the function.
.EXAMPLE
PS C:\> Get-LocalGroupMembership
Dump the Group Membership for the User that executes the function
.EXAMPLE
PS C:\> Get-LocalGroupMembership -UserName 'CONTOSO\John.Doe'
Dump the Group Membership for the User John.Doe in the Domain CONTOSO
.EXAMPLE
PS C:\> Get-LocalGroupMembership -UserName "$env:COMPUTERNAME\John.Doe"
Dump the Group Membership for the User John.Doe on the local computer
.EXAMPLE
PS C:\> Get-LocalGroupMembership -UserName 'CONTOSO\John.Doe' | Foreach-Object { Add-LocalGroupMember -Group $_ -Member "$env:COMPUTERNAME\John.Doe" -ErrorAction SilentlyContinue }
Clone the Group Membership from User John.Doe in the Domain CONTOSO to User John.Doe on the local computer
.NOTES
This is just a quick and dirty solution for a problem I faced. (See last example)
#>
[CmdletBinding(ConfirmImpact = 'None')]
[OutputType([psobject])]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
[Alias('User')]
[string]
$UserName = ("$env:USERDOMAIN" + '\' + "$env:USERNAME")
)
begin
{
# Create a new Object
$LocalGroupMembership = @()
}
process
{
$AllGroups = (Get-LocalGroup -Name *)
foreach ($LocalGroup in $AllGroups)
{
if (Get-LocalGroupMember -Group $LocalGroup.Name -ErrorAction SilentlyContinue | Where-Object -FilterScript {
$_.name -eq $UserName
})
{
$LocalGroupMembership += $LocalGroup.Name
}
}
}
end
{
# Dump the object to the console
$LocalGroupMembership
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,95 @@
function Get-LocalIpAddresses
{
<#
.SYNOPSIS
Print a string with all IP addresses
.DESCRIPTION
Print a string with all IP addresses. Supports IPv4 and IPv6.
It filters IPv6 Link Local only addresses by default.
.PARAMETER TargetName
Specifies the computers to test. Type the computer names or type IP addresses in IPv4 or IPv6 format. Wildcard characters are not permitted. The default is localhost.
.PARAMETER IPv6LinkLocal
Retuns IPv6 Link Local only addresses? Off by default.
.EXAMPLE
PS C:\> Get-LocalIpAddresses
Print a string with all local IP addresses
.EXAMPLE
PS C:\> Get-LocalIpAddresses -TargetName 'mycomputer'
Print a string with all IP addresses for the computer 'mycomputer'
.NOTES
TODO: Remove the -TargetName in the next release! Makes no sense (only IPv4 is returned)
#>
[CmdletBinding(ConfirmImpact = 'None')]
[OutputType([string])]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 1)]
[ValidateNotNullOrEmpty()]
[string]
$TargetName = $env:COMPUTERNAME,
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 2)]
[Alias('IsIPv6LinkLocal')]
[switch]
$IPv6LinkLocal
)
begin
{
$IpInfo = $null
}
process
{
$IpInfo = ($TargetName | ForEach-Object -Process {
(([Net.DNS]::GetHostAddresses([Net.Dns]::GetHostByName($_).HostName) | Where-Object -FilterScript {
$_.IsIPv6LinkLocal -eq $IPv6LinkLocal
}).IPAddressToString)
})
}
end
{
# Dump to the Console
$IpInfo
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,158 @@
function Get-etLatestNuGetRelease
{
<#
.SYNOPSIS
Get the latest published version of a given Module from a NuGet Repository
.DESCRIPTION
Get the latest published version of a given PowerShell Module from a NuGet Repository
.PARAMETER Project
Name of the Project, e.g. et.Office365
.PARAMETER Repository
NuGet Repository, default is the PowerShell Gallery
.PARAMETER Version
Return a PowerShell Version String instead of a String
.EXAMPLE
PS C:\> Get-etLatestNuGetRelease -Project 'et.Office365'
Get the latest published version of a given Module from a NuGet Repository
.EXAMPLE
PS C:\> Get-etLatestNuGetRelease -Project 'et.Office365' -version
Get the latest published version of a given Module from a NuGet Repository, but as Version instead of a String
.EXAMPLE
PS C:\> 'et.Office365' | Get-etLatestNuGetRelease
Get the latest published version of a given Module from a NuGet Repository
.NOTES
enabling Technology internal Build helper function
.LINK
Get-etModuleVersion
.LINK
Compare-enModuleVersions
.LINK
Find-Module
#>
[CmdletBinding(ConfirmImpact = 'None')]
[OutputType([string])]
param
(
[Parameter(Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 1,
HelpMessage = 'Name of the Project, e.g. et.Office365')]
[ValidateNotNullOrEmpty()]
[Alias('etProject')]
[string]
$Project,
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 2)]
[ValidateNotNullOrEmpty()]
[Alias('etRepository', 'Gallery', 'NuGetGallery')]
[string]
$Repository = 'PSGallery',
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 3)]
[Alias('enVersion')]
[switch]
$Version = $false
)
begin
{
$LatestNuGetRelease = $null
}
process
{
try
{
$paramFindModule = @{
Name = $Project
Repository = $Repository
ErrorAction = 'Stop'
WarningAction = 'SilentlyContinue'
}
$LatestNuGetRelease = (Find-Module @paramFindModule | Select-Object -ExpandProperty Version)
}
catch
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# Retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# Output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
Write-Error -Message ($info.Exception) -TargetObject ($info.Target) -ErrorAction Stop
break
}
}
end
{
if ($Version)
{
[version]$LatestNuGetRelease = $LatestNuGetRelease
}
else
{
[string]$LatestNuGetRelease = $LatestNuGetRelease
}
# Dump to the console
$LatestNuGetRelease
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,131 @@
function Grant-LogOnAsService
{
<#
.SYNOPSIS
Grant user log on as a service right in PowerShell
.DESCRIPTION
Grant user log on as a service right in PowerShell
.PARAMETER Users
The User that should get the grant
.INPUTS
String, Multi Value is OK here
.OUTPUTS
None
.EXAMPLE
PS C:\> Grant-LogOnAsService -Users 'johndoe'
Grant user log on as a service right in PowerShell
.LINK
https://gist.github.com/ned1313/9143039
.NOTES
Just a minor refactoring of the original
#>
[CmdletBinding(ConfirmImpact = 'Low',
SupportsShouldProcess)]
param
(
[Parameter(Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 1,
HelpMessage = 'The User that should get the grant')]
[ValidateNotNullOrEmpty()]
[string[]]
$Users
)
process
{
if ($pscmdlet.ShouldProcess('Apply login as a service', "$Users"))
{
# Get list of currently used SIDs
& "$env:windir\system32\secedit.exe" /export /cfg tempexport.inf
$curSIDs = (Select-String -Path .\tempexport.inf -Pattern 'SeServiceLogonRight')
$Sids = $curSIDs.line
$sidstring = ''
foreach ($user in $Users)
{
$objUser = (New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList ($user))
$strSID = $objUser.Translate([Security.Principal.SecurityIdentifier])
if (!$Sids.Contains($strSID) -and !$Sids.Contains($user))
{
$sidstring += ",*$strSID"
}
}
if ($sidstring)
{
$newSids = $Sids + $sidstring
Write-Output -InputObject ('New Sids: {0}' -f $newSids)
$tempinf = (Get-Content -Path tempexport.inf)
$tempinf = $tempinf.Replace($Sids, $newSids)
$null = (Add-Content -Path tempimport.inf -Value $tempinf -Force -Confirm:$false)
& "$env:windir\system32\secedit.exe" /import /db secedit.sdb /cfg '.\tempimport.inf'
& "$env:windir\system32\secedit.exe" /configure /db secedit.sdb
& "$env:windir\system32\gpupdate.exe" /force
}
else
{
Write-Output -InputObject 'No new sids'
}
}
}
end
{
if ($pscmdlet.ShouldProcess('Cleanup', 'Tempfiles'))
{
# Splat the Defaults
$paramRemoveItem = @{
Force = $true
Confirm = $false
ErrorAction = 'SilentlyContinue'
}
$null = (Remove-Item -Path '.\tempimport.inf' @paramRemoveItem)
$null = (Remove-Item -Path '.\secedit.sdb' @paramRemoveItem)
$null = (Remove-Item -Path '.\tempexport.inf' @paramRemoveItem)
}
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,439 @@
function Add-HostsEntry
{
<#
.SYNOPSIS
Add a single Hosts Entry to the HOSTS File
.DESCRIPTION
Add a single Hosts Entry to the HOSTS File, multiple are not supported yet!
.PARAMETER Path
The path to the hosts file where the entry should be set. Defaults to the local computer's hosts file.
.PARAMETER Address
The Address address for the hosts entry.
.PARAMETER HostName
The hostname for the hosts entry.
.PARAMETER force
Force (replace)
.EXAMPLE
PS C:\> Add-HostsEntry -Address '0.0.0.0' -HostName 'badhost'
Add the host 'badhost' with the Adress '0.0.0.0' (blackhole) wo the Hosts.
If an Entry for 'badhost' exists, the new one will be appended anyway (You end up with two entries)
.EXAMPLE
PS C:\> Add-HostsEntry -Address '0.0.0.0' -HostName 'badhost' -force
Add the host 'badhost' with the Adress '0.0.0.0' (blackhole) wo the Hosts.
If an Entry for 'badhost' exists, the new one will replace the existing one.
.NOTES
Internal Helper, inspired by an old GIST I found
.LINK
Get-HostsFile
.LINK
Remove-HostsEntry
.LINK
https://gist.github.com/markembling/173887/1824b370be3fe468faceaed5f39b12bad010a417
#>
[CmdletBinding(ConfirmImpact = 'Medium',
SupportsShouldProcess)]
param
(
[Parameter(Mandatory,
Position = 0,
HelpMessage = 'The IP address for the hosts entry.')]
[ValidateNotNullOrEmpty()]
[Alias('ipaddress', 'ip')]
[string]
$Address,
[Parameter(Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 1,
HelpMessage = 'The hostname for the hosts entry.')]
[ValidateNotNullOrEmpty()]
[Alias('Host', 'Name')]
[string]
$HostName,
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 3)]
[switch]
$force = $false,
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 2)]
[ValidateNotNullOrEmpty()]
[Alias('filename', 'Hosts', 'hostsfile', 'file')]
[string]
$Path = "$env:windir\System32\drivers\etc\hosts"
)
begin
{
Write-Verbose -Message 'Start'
}
process
{
if ($force)
{
try
{
$null = (Remove-HostsEntry -HostName $HostName -Path $Path -ErrorAction SilentlyContinue -WarningAction SilentlyContinue)
}
catch
{
Write-Verbose -Message 'Looks like the entry was not there before'
}
}
try
{
if ($pscmdlet.ShouldProcess('Target', 'Operation'))
{
# Get a clean (end of) file
$paramGetContent = @{
Path = $Path
Raw = $true
Force = $true
ErrorAction = 'Stop'
WarningAction = 'SilentlyContinue'
}
$HostsFileContent = (((Get-Content @paramGetContent ).TrimEnd()).ToString())
$NewValue = "`n" + $Address + "`t`t" + $HostName
$NewHostsFileContent = $HostsFileContent + $NewValue
$paramSetContent = @{
Path = $Path
Value = $NewHostsFileContent
Force = $true
Confirm = $false
Encoding = 'UTF8'
ErrorAction = 'Stop'
WarningAction = 'SilentlyContinue'
}
$null = (Set-Content @paramSetContent)
}
}
catch
{
# get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
$info | Out-String | Write-Verbose
Write-Error -Message ($info.Exception) -ErrorAction Stop
# Only here to catch a global ErrorAction overwrite
break
}
}
end
{
Write-Verbose -Message 'Done'
}
}
function Remove-HostsEntry
{
<#
.SYNOPSIS
Removes a single Hosts Entry from the HOSTS File
.DESCRIPTION
Removes a single Hosts Entry from the HOSTS File, multiple are not supported yet!
.PARAMETER Path
The path to the hosts file where the entry should be set. Defaults to the local computer's hosts file.
.PARAMETER HostName
The hostname for the hosts entry.
.EXAMPLE
PS C:\> Remove-HostsEntry -HostName 'Dummy'
Remove the entry for the host 'Dummy' from the HOSTS File
.NOTES
Internal Helper, inspired by an old GIST I found
.LINK
Get-HostsFile
.LINK
Add-HostsEntry
.LINK
https://gist.github.com/markembling/173887/1824b370be3fe468faceaed5f39b12bad010a417
#>
[CmdletBinding(ConfirmImpact = 'Medium',
SupportsShouldProcess)]
param
(
[Parameter(Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 0,
HelpMessage = 'The hostname for the hosts entry.')]
[ValidateNotNullOrEmpty()]
[Alias('Host', 'Name')]
[string]
$HostName,
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 1)]
[ValidateNotNullOrEmpty()]
[Alias('Hosts', 'hostsfile', 'file', 'Filename')]
[string]
$Path = "$env:windir\System32\drivers\etc\hosts"
)
begin
{
Write-Verbose -Message 'Start'
try
{
$paramGetContent = @{
Path = $Path
Raw = $true
Force = $true
ErrorAction = 'Stop'
WarningAction = 'SilentlyContinue'
}
$HostsFileContent = (((Get-Content @paramGetContent ).TrimEnd()).ToString())
}
catch
{
# get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
$info | Out-String | Write-Verbose
Write-Error -Message ($info.Exception) -ErrorAction Stop
# Only here to catch a global ErrorAction overwrite
break
}
$newLines = @()
}
process
{
foreach ($line in $HostsFileContent)
{
$bits = [regex]::Split($line, '\t+')
if ($bits.count -eq 2)
{
if ($bits[1] -ne $HostName)
{
$newLines += $line
}
}
else
{
$newLines += $line
}
}
# Write file
try
{
if ($pscmdlet.ShouldProcess('Target', 'Operation'))
{
$paramClearContent = @{
Path = $Path
Force = $true
Confirm = $false
ErrorAction = 'Stop'
WarningAction = 'SilentlyContinue'
}
$null = (Clear-Content @paramClearContent)
$paramSetContent = @{
Path = $Path
Value = $newLines
Force = $true
Confirm = $false
Encoding = 'UTF8'
ErrorAction = 'Stop'
WarningAction = 'SilentlyContinue'
}
$null = (Set-Content @paramSetContent)
}
}
catch
{
# get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
$info | Out-String | Write-Verbose
Write-Error -Message ($info.Exception) -ErrorAction Stop
# Only here to catch a global ErrorAction overwrite
break
}
}
end
{
Write-Verbose -Message 'Done'
}
}
function Get-HostsFile
{
<#
.SYNOPSIS
Print the HOSTS File in a more clean format
.DESCRIPTION
Print the HOSTS File in a more clean format
.PARAMETER Path
The path to the hosts file where the entry should be set. Defaults to the local computer's hosts file.
.PARAMETER raw
Print raw Hosts File
.EXAMPLE
PS C:\> Get-HostsFile
Print the HOSTS File in a more clean format
.EXAMPLE
PS C:\> Get-HostsFile -raw
Print the HOSTS File in the regular format
.NOTES
Internal Helper, inspired by an old GIST I found
.LINK
Add-HostsEntry
.LINK
Remove-HostsEntry
.LINK
https://gist.github.com/markembling/173887/1824b370be3fe468faceaed5f39b12bad010a417
#>
[CmdletBinding(ConfirmImpact = 'None')]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 0)]
[ValidateNotNullOrEmpty()]
[Alias('Hosts', 'hostsfile', 'file', 'filename')]
[string]
$Path = "$env:windir\System32\drivers\etc\hosts",
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 1)]
[Alias('plain')]
[switch]
$raw = $false
)
begin
{
$HostsFileContent = Get-Content -Path $Path
}
process
{
foreach ($line in $HostsFileContent)
{
if ($raw)
{
Write-Output -InputObject $line
}
else
{
$bits = [regex]::Split($line, '\t+')
if ($bits.count -eq 2)
{
[string]$HostsFileLine = $bits
if (-not ($HostsFileLine.StartsWith('#')))
{
Write-Output -InputObject $HostsFileLine
}
}
}
}
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,183 @@
function Install-DSCResourceKit
{
<#
.SYNOPSIS
Install the complete PowerShell DSCResourceKit
.DESCRIPTION
Install the complete PowerShell DSCResourceKit from the PowerShell Gallery.
It only installs the missing resources.
.PARAMETER Scope
Specifies the installation scope of the module. The acceptable values for this parameter are: AllUsers and CurrentUser.
The AllUsers scope lets modules be installed in a location that is accessible to all users of the computer, that is, %systemdrive%:\ProgramFiles\WindowsPowerShell\Modules.
The CurrentUser scope lets modules be installed only to $home\Documents\WindowsPowerShell\Modules, so that the module is available only to the current user.
.EXAMPLE
PS C:\> Install-DSCResourceKit
Install the complete PowerShell DSCResourceKit
.EXAMPLE
PS C:\> Install-DSCResourceKit -verbose
Install the complete PowerShell DSCResourceKit
.NOTES
Releasenotes:
1.0.0 2019-04-10: Internal Release
THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
Dependencies:
PowerShellGet
.LINK
https://aka.ms/InstallModule
.LINK
https://www.powershellgallery.com
#>
[CmdletBinding(ConfirmImpact = 'None',
SupportsShouldProcess)]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 0)]
[ValidateSet('AllUsers', 'CurrentUser', IgnoreCase = $true)]
[Alias('ModuleScope')]
[String]
$Scope = 'AllUsers'
)
begin
{
try
{
if (-not ($Scope))
{
$Scope = 'AllUsers'
}
$AllReSources = ((Find-Module -Tag DSCResourceKit).name)
$AllInstall = ((Get-Module -ListAvailable).Name)
}
catch
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# Retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
$info | Out-String | Write-Verbose
# Whoops
Write-Error -Message $info.Exception -ErrorAction Stop
}
}
process
{
if ($pscmdlet.ShouldProcess('DSCResourceKit', 'Install'))
{
foreach ($DSCResource in $AllReSources)
{
if (-not ($AllInstall.Contains($DSCResource)))
{
try
{
Write-Verbose -Message ('Try to install {0}' -f $DSCResource)
$paramInstallModule = @{
Name = $DSCResource
Scope = $Scope
AllowClobber = $true
SkipPublisherCheck = $true
Repository = 'PSGallery'
Force = $true
ErrorAction = 'Stop'
}
$null = (Install-Module @paramInstallModule)
Write-Verbose -Message ('Installed {0}' -f $DSCResource)
}
catch
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# Retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
$info | Out-String | Write-Verbose
Write-Warning -Message ('Unable to install {0}' -f $DSCResource) -ErrorAction Continue -WarningAction Continue
# Cleanup
$e = $null
$info = $null
}
}
else
{
Write-Verbose -Message ('{0} is already installed' -f $DSCResource)
}
}
}
}
end
{
# Cleanup
$AllReSources = $null
$AllInstall = $null
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,360 @@
function Invoke-CheckPowerShellModules
{
<#
.SYNOPSIS
Check if one or more given modules are installed.
.DESCRIPTION
Check if one or more given modules are installed.
Any missing modules can be installed (optional) and updated to the latest version available on the PowerShell Gallery can be applied (optional).
.PARAMETER Module
One or more modules to check, update, install.
.PARAMETER Install
Install any missing modules from the PowerShell Gallery?
.PARAMETER Update
Updated to the latest PowerShell Gallery Version of the module, if available?
.PARAMETER Scope
Specifies the installation scope of the module.
The acceptable values for this parameter are: AllUsers and CurrentUser.
The default is CurrentUser.
The AllUsers scope lets modules be installed in a location that is accessible to all users of the computer,
that is, %systemdrive%:\ProgramFiles\WindowsPowerShell\Modules. Elevated Shell required!
The CurrentUser scope lets modules be installed only to $home\Documents\WindowsPowerShell\Modules,
so that the module is available only to the current user.
.EXAMPLE
PS C:\> Invoke-CheckPowerShellModules -Module 'MSOnline', 'azuread', 'AzureADPreview', 'Microsoft.Online.SharePoint.PowerShell', 'MicrosoftTeams', 'Microsoft.PowerApps.PowerShell', 'Microsoft.PowerApps.Administration.PowerShell', 'SharePointPnPPowerShellOnline', 'credentialmanager' -Install
Check if all the Office 365 related PowerShell Modules are installed.
This will not install anything missing; it just runs a check!
.EXAMPLE
PS C:\> Invoke-CheckPowerShellModules -Module 'MSOnline', 'azuread', 'AzureADPreview', 'Microsoft.Online.SharePoint.PowerShell', 'MicrosoftTeams', 'Microsoft.PowerApps.PowerShell', 'Microsoft.PowerApps.Administration.PowerShell', 'SharePointPnPPowerShellOnline', 'credentialmanager' -Install
Install all the Office 365 related PowerShell Modules if anything is missing.
.EXAMPLE
PS C:\> Invoke-CheckPowerShellModules -Module 'MSOnline', 'azuread', 'AzureADPreview', 'Microsoft.Online.SharePoint.PowerShell', 'MicrosoftTeams', 'Microsoft.PowerApps.PowerShell', 'Microsoft.PowerApps.Administration.PowerShell', 'SharePointPnPPowerShellOnline', 'credentialmanager' -Scope AllUsers
Install all the Office 365 related PowerShell Modules if anything is missing (system wide).
This required to runn in an elevated Shell!!!
.EXAMPLE
PS C:\> Invoke-CheckPowerShellModules -Module 'MSOnline', 'azuread', 'AzureADPreview', 'Microsoft.Online.SharePoint.PowerShell', 'MicrosoftTeams', 'Microsoft.PowerApps.PowerShell', 'Microsoft.PowerApps.Administration.PowerShell', 'SharePointPnPPowerShellOnline', 'credentialmanager' -Update
Install all the Office 365 related PowerShell Modules if missing, automatically updates the latest version (if there is any update available)
.NOTES
For now, only the PowerShell Gallery is supported as Repository!
The next version might bring the check for an elevated shell if the scope is set to 'AllUsers'.
Releasenotes:
1.0.1 2019-05-24: Make it a bit more robust and add some examples (intial public release)
1.0.0 2019-05-15: Initial Release (internal)
THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
#>
[CmdletBinding(ConfirmImpact = 'Low',
SupportsShouldProcess)]
param
(
[Parameter(Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 0,
HelpMessage = 'One or more Modules to check.')]
[ValidateNotNullOrEmpty()]
[string[]]
$Module,
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 1)]
[Alias('AutoInstall', 'InstallMissing')]
[switch]
$Install = $null,
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 2)]
[Alias('AutoUpdate')]
[switch]
$Update = $null,
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 3)]
[ValidateNotNullOrEmpty()]
[ValidateSet('AllUsers', 'CurrentUser', IgnoreCase = $true)]
[Alias('InstallScope', 'ModuleScope')]
[string]
$Scope = 'CurrentUser'
)
begin
{
# The default scope is the current user (if not given)
if (-not $Scope)
{
$Scope = 'CurrentUser'
}
# Mandatory PowerShell Modules for Office 365 administration.
if (-not $Module)
{
$Module = 'MSOnline', 'azuread', 'AzureADPreview', 'Microsoft.Online.SharePoint.PowerShell', 'MicrosoftTeams', 'Microsoft.PowerApps.PowerShell', 'Microsoft.PowerApps.Administration.PowerShell'
}
}
process
{
foreach ($PowerShellModule in $Module)
{
# Cleanup
$InstalledModuleVersion = $null
$LatestModuleVersion = $null
$UpdateVersion = $null
try
{
Write-Verbose -Message ('Start processing for {0}' -f $PowerShellModule)
# Cleanup
$InstalledModuleVersion = $null
# In some cases, we might have different versions installed.
# We just want to have the latest and greatest one.
$paramGetModule = @{
Name = $PowerShellModule
ListAvailable = $true
ErrorAction = 'Stop'
}
$InstalledModuleVersion = (Get-Module @paramGetModule | Select-Object -Property Name, Version, repositorysourcelocation | Sort-Object -Property Version -Descending | Select-Object -First 1)
if (-not $InstalledModuleVersion)
{
if ($Install)
{
Write-Verbose -Message ('Start the installation of {0}' -f $PowerShellModule)
try
{
if ($pscmdlet.ShouldProcess($PowerShellModule, 'Install'))
{
$paramInstallModule = @{
Name = $PowerShellModule
Repository = 'PSGallery'
ErrorAction = 'Stop'
WarningAction = 'Continue'
Scope = $Scope
Force = $true
AllowClobber = $true
}
$null = (Install-Module @paramInstallModule)
}
}
catch
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# Build the Info object
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# Do some verbose things
$info | Out-String | Write-Verbose
$paramWriteError = @{
Message = $e.Exception.Message
ErrorAction = 'Stop'
Exception = $e.Exception
TargetObject = $e.CategoryInfo.TargetName
}
Write-Error @paramWriteError
}
Write-Verbose -Message ('Finished the installation of {0}' -f $PowerShellModule)
}
else
{
# Error message
Write-Error -Message ('{0} was not found...' -f $PowerShellModule) -Category NotInstalled -ErrorAction Stop
}
}
else
{
if ($InstalledModuleVersion.RepositorySourceLocation.Authority -ne 'www.powershellgallery.com')
{
Write-Error -Message ('Sorry, but only modules from the PowerShell Gallery are supported and {0} is not installed from there.' -f $PowerShellModule) -Category InvalidType -ErrorAction Stop
}
else
{
try
{
Write-Verbose -Message ('Get the latest PowerShell Gallery version for {0}' -f $PowerShellModule)
$paramFindModule = @{
Name = $PowerShellModule
Repository = 'PSGallery'
ErrorAction = 'Stop'
}
$LatestModuleVersion = (Find-Module @paramFindModule | Select-Object -Property Name, Version)
$UpdateVersion = $LatestModuleVersion.Version
Write-Verbose -Message ('Found version {0} of {1} in the PowerShell Gallery' -f $UpdateVersion, $PowerShellModule)
if ($InstalledModuleVersion.Version -ilt $UpdateVersion)
{
Write-Verbose -Message ('Version {0} for {1} is availible in the PowerShell Galery' -f $UpdateVersion, $PowerShellModule)
if ($Update)
{
Write-Verbose -Message ('Start the update for {0} to version {1}' -f $PowerShellModule, $UpdateVersion)
try
{
if ($pscmdlet.ShouldProcess($PowerShellModule, 'Update'))
{
$paramInstallModule = @{
Name = $PowerShellModule
Repository = 'PSGallery'
ErrorAction = 'Stop'
WarningAction = 'Continue'
Scope = $Scope
Force = $true
AllowClobber = $true
}
$null = (Install-Module @paramInstallModule)
}
Write-Verbose -Message ('Installed version {0} for {1}' -f $UpdateVersion, $PowerShellModule)
}
catch
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# Create the Info Object
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# Do some verbose stuff
$info | Out-String | Write-Verbose
Write-Warning -Message $e.Exception.Message
}
}
else
{
Write-Warning -Message ('Version {0} for {1} is availible on the PowerShell Galery' -f $UpdateVersion, $PowerShellModule)
}
}
else
{
Write-Verbose -Message ('No update found for {0}' -f $PowerShellModule)
}
}
catch
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# Create the Info Object
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# Do some verbose stuff
$info | Out-String | Write-Verbose
Write-Warning -Message $e.Exception.Message
}
}
}
}
catch
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# Create the Info Object
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# Do some verbose stuff
$info | Out-String | Write-Verbose
$paramWriteError = @{
Message = $e.Exception.Message
ErrorAction = 'Stop'
Exception = $e.Exception
TargetObject = $e.CategoryInfo.TargetName
}
Write-Error @paramWriteError
}
}
}
end
{
Write-Verbose -Message 'Done'
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,269 @@
#requires -Version 3.0 -Modules @{ ModuleName="PowerShellGet"; ModuleVersion="2.0.0" } -RunAsAdministrator
<#
.SYNOPSIS
Remove older versions of a installed PowerShell module
.DESCRIPTION
Remove older versions of a installed PowerShell module
.EXAMPLE
PS C:\> .\Invoke-CleanupOldGalleryModuleVersions.ps1
.EXAMPLE
PS C:\> .\Invoke-CleanupOldGalleryModuleVersions.ps1 -Verbose
.EXAMPLE
PS C:\> .\Invoke-CleanupOldGalleryModuleVersions.ps1 -Verbose
.EXAMPLE
PS C:\> .\Invoke-CleanupOldGalleryModuleVersions.ps1 -debug
.NOTES
This is a replacement for some older functions
.LINK
Invoke-UpdateAllGalleryModules.ps1
#>
[CmdletBinding(ConfirmImpact = 'Low',
SupportsShouldProcess)]
param ()
begin
{
#region Defaults
$STP = 'Stop'
$CNT = 'Continue'
$SCT = 'SilentlyContinue'
#endregion Defaults
#region Cleanup
$AllModules = $null
#endregion Cleanup
#region BoundParameters
if (($PSCmdlet.MyInvocation.BoundParameters['Verbose']).IsPresent)
{
$VerboseValue = $true
}
else
{
$VerboseValue = $false
}
if (($PSCmdlet.MyInvocation.BoundParameters['Debug']).IsPresent)
{
$DebugValue = $true
}
else
{
$DebugValue = $false
}
if (($PSCmdlet.MyInvocation.BoundParameters['WhatIf']).IsPresent)
{
$WhatIfValue = $true
}
else
{
$WhatIfValue = $false
}
#endregion BoundParameters
}
process
{
# Get the Module information
$paramGetModule = @{
ListAvailable = $true
Refresh = $true
ErrorAction = $CNT
WarningAction = $CNT
Verbose = $VerboseValue
Debug = $DebugValue
}
$AllModules = (Get-Module @paramGetModule | Where-Object -FilterScript {
$_.RepositorySourceLocation -like '*powershellgallery*'
} | Select-Object -ExpandProperty Name)
$AllModules = ($AllModules | Sort-Object -Unique)
foreach ($ModuleName in $AllModules)
{
Write-Verbose -Message ('Get all existing versions of {0}' -f $ModuleName)
$AllModuleVersions = $null
$AllModuleVersions = (Get-InstalledModule -Name $ModuleName -AllVersions -ErrorAction $SCT -WarningAction $CNT)
if (((($AllModuleVersions).Version).count) -gt 1)
{
$LatestModuleVersion = $null
$LatestModuleVersion = (($AllModuleVersions | Sort-Object -Property $AllModuleVersions.Version)[1])
try
{
$output = $null
$output = ($AllModuleVersions | Where-Object {
(($_.Version) -lt ($LatestModuleVersion.Version))
} | ForEach-Object -Process {
Write-Verbose -Message ('Start to process {0}' -f ($_).Name)
try
{
$paramUninstallModule = @{
Name = $_
Force = $true
Confirm = $false
WhatIf = $WhatIfValue
Verbose = $VerboseValue
Debug = $DebugValue
ErrorAction = $STP
WarningAction = $CNT
}
Uninstall-Module @paramUninstallModule
}
catch
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
$paramWriteError = @{
Message = $e.Exception.Message
ErrorAction = $CNT
Exception = $e.Exception
TargetObject = $e.CategoryInfo.TargetName
}
Write-Error @paramWriteError
}
finally
{
if (Test-Path -Path $_.InstalledLocation -ErrorAction $SCT -WarningAction $SCT)
{
Write-Verbose -Message ('Try to remove {0}' -f ($_).InstalledLocation)
try
{
$paramRemoveItem = @{
Path = $_.InstalledLocation
Recurse = $true
Force = $true
Confirm = $false
ErrorAction = $STP
WarningAction = $CNT
WhatIf = $WhatIfValue
Verbose = $VerboseValue
Debug = $DebugValue
}
Remove-Item @paramRemoveItem
Write-Verbose -Message ('Removed {0}' -f ($_).InstalledLocation)
}
catch
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
$paramWriteError = @{
Message = $e.Exception.Message
ErrorAction = $STP
Exception = $e.Exception
TargetObject = $e.CategoryInfo.TargetName
}
Write-Error @paramWriteError
}
}
}
Write-Verbose -Message ('Removed old versions off {0}' -f ($_).Name)
})
$output
}
catch
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
Write-Warning -Message ('Failed to process {0}' -f ($_).Name)
}
}
else
{
Write-Verbose -Message ('Skip {0}' -f ($AllModuleVersions).Name)
}
}
}
end
{
$AllModules = $null
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,302 @@
#requires -Version 3.0 -Modules DnsClient
<#
.SYNOPSIS
Update CloudFlare DNS A Record if needed
.DESCRIPTION
Update CloudFlare DNS A Record if needed
The prevent to much API calls, we use a regular DNS query first.
Only if this query spot a difference, we ensure if an update is needed by ask the Cloudflare API for the latest published info.
If there is stiff a difference, the cmdlet will update the entry for you.
If you use a new/unknown hostname in the CF_HOSTNAME parameter, the cmdlet will create a new entry for the given host!
.PARAMETER CF_TOKEN
CloudFlare API Token
Hint: You can find your API key at: https://dash.cloudflare.com/profile/api-tokens
Create a dedicated Token just for this cmdlet and give it a name that indicate the purpose of it
The Token needs a least the following permission: Zone.Zone, Zone.DNS
The token needs access to at least the Zone you want to update (Resources), or use 'All zones'
.PARAMETER CF_DOMAIN
The CloudFlare DNS zone you want to modify
Example: contoso.com (this is also the default)
.PARAMETER CF_HOSTNAME
This is the A record you'd like to update or add
Example: homelab (this is also the default)
Please Note: We support A Records only at this time!
.PARAMETER DNSServer
Resolves hostname using DNS instead of checking CloudFlare.
It is recommended to use the CloudFlare DNS Servers, e.g. 1.1.1.1
You can use any other server, but mind that you might not see the changed IP until the Cache TTL expired on this Server!
.EXAMPLE
PS C:\> .\Invoke-CloudFlareDDNSUpdate.ps1 -CF_TOKEN '<TOKEN>' -CF_DOMAIN 'contoso.com' -CF_HOSTNAME 'homelab'
Check and updates the host 'homelab' in the DNS Zone 'contoso.com'
.EXAMPLE
PS C:\> .\Invoke-CloudFlareDDNSUpdate.ps1 -CF_TOKEN '<TOKEN>' -CF_DOMAIN 'contoso.com' -CF_HOSTNAME 'homelab' -Verbose
Check and updates the host 'homelab' in the DNS Zone 'contoso.com', but run in verbose mode
.EXAMPLE
PS C:\> .\Invoke-CloudFlareDDNSUpdate.ps1 -CF_TOKEN '<TOKEN>' -CF_DOMAIN 'contoso.com' -CF_HOSTNAME 'homelab' -DNSServer 1.0.0.1
Check and updates the host 'homelab' in the DNS Zone 'contoso.com', uses the backup CloudFlare DNS to get the published info
.LINK
https://1.1.1.1/dns/
.NOTES
We use a regular (cheap) DNS call to reduce the number of calls to CloudFlare (they allow 200 reqs/minute but why ask an API first?)
There is no output by the cmdlet, makes it easier if run a a service or schedules task. use the -Verbose switch to see what the cmdlet is doing
Please Note: We support A Records only at this time! We are already testing IPv6 (AAAA) and a few others.
#>
[CmdletBinding(ConfirmImpact = 'None')]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
[Alias('CLOUDFLARE_TOKEN', 'CFAPIKey', 'Token')]
[string]
$CF_TOKEN = '<Your_Super_Secret_Token_Here>',
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
[Alias('CLOUDFLARE_Domain', 'CLOUDFLARE_DomainName', 'CFDomainName', 'Zone')]
[string]
$CF_DOMAIN = 'contoso.com',
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
[Alias('CFARecord', 'CLOUDFLARE_HOST', 'CLOUDFLARE_HOSTNAME')]
[string]
$CF_HOSTNAME = 'homelab',
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
[Alias('DNSToUse')]
[string]
$DNSServer = '1.1.1.1'
)
begin
{
#region Cleanup
$CF_KnownIP = $null
$CF_ExternalIP = $null
#endregion Cleanup
#region CheapRequests
if (Get-Command -Name Resolve-DnsName -ErrorAction SilentlyContinue)
{
# Get the A record from the CloudFlare DNS (cheap request)
$paramResolveDnsName = @{
Name = ($CF_HOSTNAME + '.' + $CF_DOMAIN)
Type = 'A'
Server = $DNSServer
ErrorAction = 'SilentlyContinue'
WarningAction = 'Continue'
}
[string]$CF_KnownIP = (((Resolve-DnsName @paramResolveDnsName) | Select-Object -ExpandProperty IPAddress).Trim())
}
elseif (Get-Command -Name dig -ErrorAction SilentlyContinue)
{
# This is the Fallback on macOS, due to the missing DnsClient module on PowerShell core here
[string]$CF_KnownIP = (((dig A ($CF_HOSTNAME + '.' + $CF_DOMAIN) ('@' + $DNSServer) +short)).Trim())
}
else
{
Write-Warning -Message 'Unable to lookup the DNS entry, we try to use the CloudFlare API' -WarningAction Continue
# Set a dummy (to prevent any null pointer exception during the compare)
[string]$CF_KnownIP = '0.0.0.0'
}
# Get the external IP via Web Request from our own service (cheap request)
$paramInvokeRestMethod = @{
Method = 'Get'
UseBasicParsing = $true
Uri = 'https://ip.enatec.net'
ErrorAction = 'Stop'
WarningAction = 'Continue'
}
[string]$CF_ExternalIP = ((Invoke-RestMethod @paramInvokeRestMethod).Trim())
#endregion CheapRequests
}
process
{
# Compare the two values
if ($CF_ExternalIP -ne $CF_KnownIP)
{
# Looks like there is a Difference
# Only the V4 API is supported by the cmdlet yet!
$CF_API_ENDPOINT = $null
$CF_API_ENDPOINT = 'https://api.cloudflare.com/client/v4'
$CF_Headers = $null
$CF_Headers = @{
'Authorization' = ('Bearer ' + $CF_TOKEN)
'Content-Type' = 'application/json'
}
$CF_ZoneURI = $null
$CF_ZoneURI = ($CF_API_ENDPOINT + '/zones?name=' + $CF_DOMAIN)
Write-Verbose -Message ('Getting DNS-Zone ID for ' + $($CF_DOMAIN) + ' via ' + $CF_ZoneURI)
# Let us get the Zone Info directly from CloudFlare (API Request)
$CF_ZoneId = $null
$paramInvokeRestMethod = @{
Uri = $CF_ZoneURI
ContentType = 'application/json'
Headers = $CF_Headers
ErrorAction = 'Stop'
WarningAction = 'Continue'
}
$CF_ZoneId = (((Invoke-RestMethod @paramInvokeRestMethod).result).id)
$CF_DNSURI = $null
$CF_DNSURI = ($CF_API_ENDPOINT + '/zones/' + $CF_ZoneId + '/dns_records?type=A&name=' + $CF_HOSTNAME + '.' + $CF_DOMAIN)
Write-Verbose -Message ('Getting DNS data for ' + $($CF_HOSTNAME).$($CF_DOMAIN) + ' via ' + $CF_DNSURI)
# Let us get the host Info directly from CloudFlare (API Request)
$CF_DNSData = $null
$paramInvokeRestMethod = @{
Uri = $CF_DNSURI
ContentType = 'application/json'
Headers = $CF_Headers
ErrorAction = 'Stop'
WarningAction = 'Continue'
}
$CF_DNSData = ((Invoke-RestMethod @paramInvokeRestMethod).result)
# Compare again (Double check)
if ($CF_ExternalIP -ne $CF_DNSData.content)
{
# OK, we are sure that there is a new IP!
Write-Verbose -Message 'IP address change detected, we will try to update the CloudFlare DNS'
try
{
$CF_Body = $null
$CF_Body = @{
'type' = 'A'
'name' = ($CF_HOSTNAME + '.' + $CF_DOMAIN)
'content' = $CF_ExternalIP
'ttl' = '1'
}
$URI_Update = $null
$URI_Update = ($CF_API_ENDPOINT + '/zones/' + $CF_ZoneId + '/dns_records/' + $($CF_DNSData.id))
# Apply the new IP address to the CloudFlare DNS
$CF_Result = $null
$paramInvokeRestMethod = @{
Uri = $URI_Update
Method = 'Put'
ContentType = 'application/json'
Headers = $CF_Headers
Body = $
WebSession = ($CF_Body | ConvertTo-Json)
ErrorAction = 'Stop'
WarningAction = 'Continue'
}
$CF_Result = ((Invoke-RestMethod @paramInvokeRestMethod).result)
if ($CF_Result.content -eq $CF_ExternalIP)
{
Write-Verbose -Message 'SUCCESS: CloudFlare DNS was successfully updated'
}
else
{
Write-Verbose -Message 'FAILED: CloudFlare DNS was not successfully updated'
}
}
catch
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
$paramWriteError = @{
Message = $e.Exception.Message
ErrorAction = 'Stop'
Exception = $e.Exception
TargetObject = $e.CategoryInfo.TargetName
}
Write-Error @paramWriteError
# Just in case
exit 1
}
}
else
{
Write-Verbose -Message 'CloudFlare: No update is needed'
}
}
else
{
Write-Verbose -Message 'DNS: No update is needed'
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,159 @@
function Invoke-DSCPerfReqConfigCheck
{
<#
.SYNOPSIS
Perform Required Configuration Checks and suppress all outputs.
.DESCRIPTION
Run the DSCLocalConfigurationManager method PerformRequiredConfigurationChecks.
.PARAMETER Silent
The progress bar will be suppressed. this is not the case by default.
.EXAMPLE
PS C:\> Invoke-DSCPerfReqConfigCheck
True
# Run without any error
.EXAMPLE
PS C:\> Invoke-DSCPerfReqConfigCheck -Silent
True
# Run without any error. Suppress the progress bar.
.EXAMPLE
PS C:\> Invoke-DSCPerfReqConfigCheck
False
# The run had errors.
.EXAMPLE
PS C:\> Invoke-DSCPerfReqConfigCheck -Silent
False
# The run had errors. Suppress the progress bar.
.NOTES
I do a lot of testing with several DSC configurations.
I just want a TRUE or FALSE as return to see if its working, or not.
You may guess why: I use this in a CI chain :-)
You may want to have separated EventLog entries for DSC (useful for the log-Resource):
& "$env:windir\system32\wevtutil.exe" set-log 'Microsoft-Windows-Dsc/Analytic' /q:true /e:true
& "$env:windir\system32\wevtutil.exe" set-log 'Microsoft-Windows-Dsc/Debug' /q:True /e:true
I dedicate any and all copyright interest in this software to the public domain.
I make this dedication for the benefit of the public at large and to the detriment of my heirs and successors.
I intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law.
.LINK
Author http://jhochwald.com
.LINK
LICENSE http://unlicense.org
.LINK
Invoke-CimMethod
Write-Verbose
Get-WinEvent
#>
[OutputType([bool])]
param
(
[Parameter(ValueFromPipeline,
Position = 1)]
[switch]
$Silent = $null
)
begin
{
$SC = 'SilentlyContinue'
if ($Silent)
{
$ProgressPreference = $SC
}
}
process
{
$InvokeCimMethodParams = @{
Namespace = 'root/Microsoft/Windows/DesiredStateConfiguration'
ClassName = 'MSFT_DSCLocalConfigurationManager'
MethodName = 'PerformRequiredConfigurationChecks'
Arguments = @{
Flags = [uint32] 1
}
ErrorAction = $SC
WarningAction = $SC
}
try
{
$null = (Invoke-CimMethod @InvokeCimMethodParams)
if ($Silent)
{
$ProgressPreference = $null
}
}
catch
{
$paramWriteVerbose = @{
Message = "$_.Exception.Message - Line Number: $_.InvocationInfo.ScriptLineNumber"
ErrorAction = $SC
WarningAction = $SC
}
Write-Verbose @paramWriteVerbose
}
$GetWinEventParams = @{
LogName = 'Microsoft-Windows-Dsc/*'
ErrorAction = $SC
WarningAction = $SC
Oldest = $true
}
# TODO: That is fast, but the code looks bad!
$SuccessResult = (Get-WinEvent @GetWinEventParams | Group-Object -Property {
$_.Properties[0].value
}).Group.LevelDisplayName -notcontains 'Error'
}
end
{
return $SuccessResult
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,315 @@
#requires -Version 3.0 -Modules @{ ModuleName="PowerShellGet"; ModuleVersion="2.0.0" } -RunAsAdministrator
<#
.SYNOPSIS
Update all PowerShell Modules to the latest PowerShell Gallery version
.DESCRIPTION
Update all PowerShell Modules to the latest PowerShell Gallery version
.PARAMETER Silent
Hide the PowerShell Progress Bars
.EXAMPLE
PS C:\> .\Invoke-UpdateAllGalleryModules.ps1
Update all PowerShell Modules to the latest PowerShell Gallery version
.EXAMPLE
PS C:\> .\Invoke-UpdateAllGalleryModules.ps1 -Silent
Update all PowerShell Modules to the latest PowerShell Gallery version and hide the PowerShell Progress Bars
.EXAMPLE
PS C:\> .\Invoke-UpdateAllGalleryModules.ps1 -WhatIf
Dry run the update all PowerShell Modules to the latest PowerShell Gallery version
.EXAMPLE
PS C:\> .\Invoke-UpdateAllGalleryModules.ps1 -verbose
Update all PowerShell Modules to the latest PowerShell Gallery version in verbose mode
.EXAMPLE
PS C:\> .\Invoke-UpdateAllGalleryModules.ps1 -verbose
Update all PowerShell Modules to the latest PowerShell Gallery version in debug mode
.NOTES
This is a replacement for some older functions
.LINK
Invoke-CleanupOldGalleryModuleVersions.ps1
#>
[CmdletBinding(ConfirmImpact = 'None',
SupportsShouldProcess)]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[Alias('NoProgressBars')]
[switch]
$Silent
)
begin
{
#region Defaults
$STP = 'Stop'
$CNT = 'Continue'
$SCT = 'SilentlyContinue'
#endregion Defaults
#region Cleanup
$OriginalProgressPreference = $null
$AllModules = $null
#endregion Cleanup
#region BoundParameters
if (($PSCmdlet.MyInvocation.BoundParameters['Verbose']).IsPresent)
{
$VerboseValue = $true
}
else
{
$VerboseValue = $false
}
if (($PSCmdlet.MyInvocation.BoundParameters['Debug']).IsPresent)
{
$DebugValue = $true
}
else
{
$DebugValue = $false
}
if (($PSCmdlet.MyInvocation.BoundParameters['WhatIf']).IsPresent)
{
$WhatIfValue = $true
}
else
{
$WhatIfValue = $false
}
#endregion BoundParameters
if (($PSCmdlet.MyInvocation.BoundParameters['Silent']).IsPresent)
{
# Save the original value
$OriginalProgressPreference = $ProgressPreference
# Silence is golden...
$ProgressPreference = $SCT
}
# Get the Module information
$paramGetModule = @{
ListAvailable = $true
Refresh = $true
ErrorAction = $CNT
WarningAction = $CNT
Verbose = $VerboseValue
Debug = $DebugValue
}
$AllModules = (Get-Module @paramGetModule | Where-Object -FilterScript {
$_.RepositorySourceLocation -like '*powershellgallery*'
} | Select-Object -Property Name, Version, Path)
}
process
{
foreach ($SingleModule in $AllModules)
{
# Cleanup
$RepositoryInfo = $null
<#
The AllowPrerelease is needed here
Find-Module ignored the ErrorAction setting, try/catch will not work
#>
$paramFindModule = @{
Name = (($SingleModule).Name)
Repository = 'PSGallery'
AllowPrerelease = $true
ErrorAction = $SCT
WarningAction = $CNT
Verbose = $VerboseValue
Debug = $DebugValue
}
$RepositoryInfo = (Find-Module @paramFindModule | Select-Object -Property Name, Version)
#region CleanVersions
<#
Remove everything from the version string that violates the System.Version class
https://docs.microsoft.com/en-us/dotnet/api/system.version
e.g. -beta4 or -preview
#>
# Character that we use as a slipt
$SlipPointer = '-'
# Create the Wildcard to search for
$SplitSearch = ('*' + $SlipPointer + '*')
if (($SingleModule.Version) -like $SplitSearch)
{
$SingleModule.Version = (($SingleModule.Version).split($SlipPointer)[0])
}
if (($RepositoryInfo.Version) -like $SplitSearch)
{
$RepositoryInfo.Version = (($RepositoryInfo.Version).split($SlipPointer)[0])
}
#endregion CleanVersions
# Is the online version newer?
if ((($SingleModule).Version) -lt (($RepositoryInfo).Version))
{
# Cleanup
$ModuleScope = $null
# try to figure out the scope
if ((($SingleModule).Path) -like ($env:ProgramW6432 + '\*'))
{
$ModuleScope = 'AllUsers'
}
else
{
$ModuleScope = 'CurrentUser'
}
try
{
Write-Verbose -Message ('Try to update {0}' -f ($SingleModule).Name)
# Cleanup
$paramUpdateModule = $null
# Try the Update
$paramUpdateModule = @{
Name = (($SingleModule).Name)
Scope = $ModuleScope
Force = $true
AcceptLicense = $true
Confirm = $false
Verbose = $VerboseValue
Debug = $DebugValue
WhatIf = $WhatIfValue
ErrorAction = $STP
WarningAction = $CNT
}
$null = (Update-Module @paramUpdateModule)
}
catch
{
try
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
Write-Verbose -Message ('Retry to update {0}' -f ($SingleModule).Name)
# Cleanup
$paramUpdateModule = $null
# Re-Try the update by allowing prereleases
$paramUpdateModule = @{
Name = (($SingleModule).Name)
AllowPrerelease = $true
Scope = $ModuleScope
Force = $true
AcceptLicense = $true
Confirm = $false
Verbose = $VerboseValue
Debug = $DebugValue
WhatIf = $WhatIfValue
ErrorAction = $STP
WarningAction = $CNT
}
$null = (Update-Module @paramUpdateModule)
}
catch
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
Write-Warning -Message ('Update of {0} failed' -f ($SingleModule).Name)
}
}
}
else
{
Write-Verbose -Message ('No update for {0} found' -f ($SingleModule).Name)
}
}
}
end
{
if ($OriginalProgressPreference)
{
# Restore the old value
$ProgressPreference = $OriginalProgressPreference
}
# Cleanup
$AllModules = $null
# Have a great day!
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,29 @@
BSD 3-Clause License
Copyright (c) 2021, enabling Technology <http://enatec.io>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,311 @@
<#
.SYNOPSIS
Apply the Defender exclusions based on recommendations by Microsoft
.DESCRIPTION
Apply the Defender exclusions based on recommendations by Microsoft
.EXAMPLE
PS C:\> Optimize-MicrosoftDefenderExclusions.ps1
.NOTES
Do not just use set-mppreference here, this might remove any existing exclusions.
Might be the right thing to do, but with add-mppreference you append to the list (if exists).
.LINK
https://support.microsoft.com/en-ie/help/822158/virus-scanning-recommendations-for-enterprise-computers-that-are-runni
.LINK
https://docs.microsoft.com/en-us/powershell/module/defender/add-mppreference
.LINK
https://docs.microsoft.com/en-us/powershell/module/defender/set-mppreference
#>
[CmdletBinding(ConfirmImpact = 'Medium',
SupportsShouldProcess)]
param ()
begin
{
#region DefaultExclusions
$ExcludePathList = @(
"$env:windir\SoftwareDistribution\DataStore\Datastore.edb",
"$env:windir\SoftwareDistribution\DataStore\Logs\Edb*.jrs",
"$env:windir\SoftwareDistribution\DataStore\Logs\Edb.chk",
"$env:windir\SoftwareDistribution\DataStore\Logs\Tmp.edb",
"$env:windir\Security\Database\*.edb",
"$env:windir\Security\Database\*.sdb",
"$env:windir\Security\Database\*.log",
"$env:windir\Security\Database\*.chk",
"$env:windir\Security\Database\*.jrs",
"$env:windir\Security\Database\*.xml",
"$env:windir\Security\Database\*.csv",
"$env:windir\Security\Database\*.cmtx",
"$env:ProgramData\ntuser.pol",
"$env:windir\System32\GroupPolicy\Machine\Registry.pol",
"$env:windir\System32\GroupPolicy\Machine\Registry.tmp",
"$env:windir\System32\GroupPolicy\User\Registry.pol",
"$env:windir\System32\GroupPolicy\User\Registry.tmp"
)
#endregion DefaultExclusions
#region AdExclusions
# Turn off scanning of Active Directory and Active Directory-related files
# Exclude the Main NTDS database files.
$DSADatabaseFile = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters'
$DSADatabaseFilePath = ('Registry::' + $DSADatabaseFile)
if (Test-Path -Path $DSADatabaseFilePath)
{
$DSADatabaseFileValue = (Get-ItemProperty -Path $DSADatabaseFilePath | Select-Object -ExpandProperty 'DSA Database file' -ErrorAction SilentlyContinue)
if ($DSADatabaseFileValue)
{
$ExcludePathList += ($DSADatabaseFileValue)
$ExcludePathList += ($DSADatabaseFileValue).Replace('.dit', '.pat')
}
}
else
{
Write-Verbose -Message 'No NTDS database files to exclude'
}
# Exclude the Active Directory transaction log files.
$DatabaseLogFiles = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters'
$DatabaseLogFilesPath = ('Registry::' + $DatabaseLogFiles)
if (Test-Path -Path $DatabaseLogFilesPath)
{
$DatabaseLogFilesPathValue = (Get-ItemProperty -Path $DatabaseLogFilesPath | Select-Object -ExpandProperty 'Database Log Files Path' -ErrorAction SilentlyContinue)
if ($DatabaseLogFilesPathValue)
{
$ExcludePathList += ($DatabaseLogFilesPathValue + '\EDB*.log')
$ExcludePathList += ($DatabaseLogFilesPathValue + '\Res*.log')
$ExcludePathList += ($DatabaseLogFilesPathValue + '\Edb*.jrs')
$ExcludePathList += ($DatabaseLogFilesPathValue + '\Ntds.pat')
}
}
else
{
Write-Verbose -Message 'No Active Directory transaction log files to exclude'
}
# Exclude the files in the NTDS Working folder
$DSAWorkingDir = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters'
$DSAWorkingDirPath = ('Registry::' + $DSAWorkingDir)
if (Test-Path -Path $DSAWorkingDirPath)
{
$DSAWorkingDirValue = (Get-ItemProperty -Path $DSAWorkingDirPath | Select-Object -ExpandProperty 'DSA Working Directory' -ErrorAction SilentlyContinue)
if ($DSAWorkingDirValue)
{
$ExcludePathList += ($DSAWorkingDirValue + '\Temp.edb')
$ExcludePathList += ($DSAWorkingDirValue + '\Edb.chk')
}
}
else
{
Write-Verbose -Message 'No NTDS Working folder to exclude'
}
#endregion AdExclusions
#region SysVolExclusions
# Turn off scanning of SYSVOL files
# Turn off scanning of files in the File Replication Service (FRS) Working folder
$SysVolWorkingDir = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NtFrs\Parameters'
$SysVolWorkingDirPath = ('Registry::' + $SysVolWorkingDir)
if (Test-Path -Path $SysVolWorkingDirPath)
{
$SysVolWorkingDirValue = (Get-ItemProperty -Path $SysVolWorkingDirPath | Select-Object -ExpandProperty 'Working Directory' -ErrorAction SilentlyContinue)
if ($SysVolWorkingDirValue)
{
$ExcludePathList += ($SysVolWorkingDirValue + '\jet\sys\edb.chk')
$ExcludePathList += ($SysVolWorkingDirValue + '\jet\Ntfrs.jdb')
$ExcludePathList += ($SysVolWorkingDirValue + '\jet\log\*.log')
}
}
else
{
Write-Verbose -Message 'No File Replication Service Working folder to exclude'
}
# Turn off scanning of files in the File Replication Service Database Log files
$SysVolDBLogFileDir = 'HKEY_LOCAL_MACHINE\SYSTEM\Currentcontrolset\Services\Ntfrs\Parameters'
$SysVolDBLogFileDirPath = ('Registry::' + $SysVolDBLogFileDir)
if (Test-Path -Path $SysVolDBLogFileDirPath)
{
$SysVolDBLogFileDirValue = (Get-ItemProperty -Path $SysVolWorkingDirPath | Select-Object -ExpandProperty 'Working Directory' -ErrorAction SilentlyContinue)
if ($SysVolDBLogFileDirValue)
{
$ExcludePathList += ($SysVolDBLogFileDirValue + '\Jet\Log\Edb*.jrs')
}
else
{
if ($SysVolWorkingDirValue)
{
$ExcludePathList += ($SysVolWorkingDirValue + '\jet\Log\Edb*.log')
}
}
}
else
{
Write-Verbose -Message 'No File Replication Service Database Log files to exclude'
}
#endregion SysVolExclusions
#region DhcpExclusions
# Turn off scanning of DHCP files
$DhcpFiles = 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\DHCPServer\Parameters'
$DhcpFilesPath = ('Registry::' + $DhcpFiles)
if (Test-Path -Path $DhcpFilesPath)
{
$DhcpDatabasePathValue = (Get-ItemProperty -Path $DhcpFilesPath | Select-Object -ExpandProperty 'DatabasePath' -ErrorAction SilentlyContinue)
if ($DhcpDatabasePathValue)
{
$ExcludePathList += ($DhcpDatabasePathValue + '\*.mdb')
$ExcludePathList += ($DhcpDatabasePathValue + '\*.pat')
$ExcludePathList += ($DhcpDatabasePathValue + '\*.chk')
$ExcludePathList += ($DhcpDatabasePathValue + '\*.edb')
}
$DhcpLogFilePathValue = (Get-ItemProperty -Path $DhcpFilesPath | Select-Object -ExpandProperty 'DhcpLogFilePath' -ErrorAction SilentlyContinue)
if (($DhcpLogFilePathValue) -and ($DhcpLogFilePathValue -ne $DhcpDatabasePathValue))
{
$ExcludePathList += ($DhcpLogFilePathValue + '\*.log')
}
else
{
$ExcludePathList += ($DhcpDatabasePathValue + '\*.log')
}
$DhcpBackupDatabasePathValue = (Get-ItemProperty -Path $DhcpFilesPath | Select-Object -ExpandProperty 'BackupDatabasePath' -ErrorAction SilentlyContinue)
if ($DhcpBackupDatabasePathValue)
{
$ExcludePathList += ($DhcpBackupDatabasePathValue + '\new\*.mdb')
$ExcludePathList += ($DhcpBackupDatabasePathValue + '\new\*.pat')
$ExcludePathList += ($DhcpBackupDatabasePathValue + '\new\*.chk')
$ExcludePathList += ($DhcpBackupDatabasePathValue + '\new\*.edb')
$ExcludePathList += ($DhcpBackupDatabasePathValue + '\new\*.log')
}
}
else
{
Write-Verbose -Message 'No DHCP Server Directory found'
}
#endregion DhcpExclusions
#region DnsExclusions
$DnsServerDir = "$env:windir\System32\dns"
if (Test-Path -Path $DnsServerDir -ErrorAction SilentlyContinue)
{
$ExcludePathList += ($DnsServerDir + '\*.log')
$ExcludePathList += ($DnsServerDir + '\*.dns')
$ExcludePathList += ($DnsServerDir + '\BOOT')
$DnsBackupServerDir = ($DnsServerDir + '\backup')
if (Test-Path -Path $DnsBackupServerDir -ErrorAction SilentlyContinue)
{
$ExcludePathList += ($DnsBackupServerDir + '\*.log')
$ExcludePathList += ($DnsBackupServerDir + '\*.dns')
$ExcludePathList += ($DnsBackupServerDir + '\BOOT')
}
}
else
{
Write-Verbose -Message 'No DNS Server Directory found'
}
#endregion DnsExclusions
#region WinsExclusions
$WinsServerDir = "$env:windir\System32\Wins"
if (Test-Path -Path $WinsServerDir -ErrorAction SilentlyContinue)
{
Write-Warning -Message 'WINS is still installed on this system!' -WarningAction Continue
$ExcludePathList += ($WinsServerDir + '\*.chk')
$ExcludePathList += ($WinsServerDir + '\*.log')
$ExcludePathList += ($WinsServerDir + '\*.mdb')
}
else
{
Write-Verbose -Message 'No WINS Server Directory found'
}
#endregion WinsExclusions
}
process
{
if ($pscmdlet.ShouldProcess($ExcludePathList, 'Exclude from Microsoft Defender Scanning'))
{
# Loop over the list we created
foreach ($ExcludePath in $ExcludePathList)
{
try
{
# Splat the parameters for Add-MpPreference
$SplatAddMpPreference = @{
ExclusionPath = $ExcludePath
Force = $true
ErrorAction = 'Stop'
WarningAction = 'Continue'
}
$null = (Add-MpPreference @SplatAddMpPreference)
}
catch
{
#region ErrorHandler
# get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = @{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# Error Stack
$info | Out-String | Write-Verbose
# Just display the info on continue with the rest of the list
Write-Warning -Message ($info.Exception) -ErrorAction Continue -WarningAction Continue
# Cleanup
$info = $null
$e = $null
#endregion ErrorHandler
}
}
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,133 @@
<#
.SYNOPSIS
Add Defender Antivirus Exclusions for the Teams Desktop Client for a given User
.DESCRIPTION
Add Defender Antivirus Exclusions for the Teams Desktop Client for a given User
.PARAMETER Username
Username to apply the exclusion to.
Please Note: The user 'john.doe' in the domain 'CONTOSO' will have the username 'john.doe.CONTOSO'. This is the case to have the connect Directory (Windows naming convention).
.EXAMPLE
PS C:\> .\Optimize-MicrosoftDefenderExclusionsForMicrosoftTeams.ps1 -Username 'john.doe.CONTOSO'
Apply the Defender Antivirus Exclusions for the user 'john.doe' in the domain 'CONTOSO'.
In this case, the $env:USERPROFILE Directory will be 'C:\Users\john.doe.CONTOSO'
.NOTES
This is a more flexible version of Add-DefenderExclusionsForMicrosoftteams.ps1 that brings username as a parameter.
I crerated this because my user does NOT have Admin permissions on my local windows boxes and with this version, I can apply it with my admin account, biut for my regular user (or any other user on the local system)
Do not just use set-mppreference here, this might remove any existing exclusions.
Might be the right thing to do, but with add-mppreference you append to the list (if exists).
.LINK
https://gist.github.com/jhochwald/866ce1c5ac894397979f38fa9720b8ff
.LINK
https://docs.microsoft.com/en-us/powershell/module/defender/add-mppreference
.LINK
https://docs.microsoft.com/en-us/powershell/module/defender/set-mppreference
#>
[CmdletBinding(ConfirmImpact = 'Low',
SupportsShouldProcess)]
param
(
[Parameter(Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 0,
HelpMessage = 'Username to apply the exclusion to.')]
[ValidateNotNullOrEmpty()]
[Alias('User', 'Name')]
[string]
$Username
)
begin
{
$ExcludePathList = @(
('C:\Users\' + $Username + '\Microsoft\Teams\Update.exe'),
('C:\Users\' + $Username + '\Microsoft\Teams\current\Teams.exe'),
('C:\Users\' + $Username + '\Microsoft\Teams\'),
('C:\Users\' + $Username + '\Microsoft\Teams\')
)
}
process
{
# Loop over the list we created
foreach ($ExcludePath in $ExcludePathList)
{
try
{
# Splat the parameters for Add-MpPreference
$SplatAddMpPreference = @{
ExclusionPath = $ExcludePath
Force = $true
ErrorAction = 'Stop'
WarningAction = 'Continue'
}
$null = (Add-MpPreference @SplatAddMpPreference)
}
catch
{
#region ErrorHandler
# get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = @{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# Error Stack
$info | Out-String | Write-Verbose
# Just display the info on continue with the rest of the list
Write-Warning -Message ($info.Exception) -ErrorAction Continue -WarningAction Continue
# Cleanup
$info = $null
$e = $null
#endregion ErrorHandler
}
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,229 @@
function Out-ZipArchive
{
<#
.SYNOPSIS
Creates a ZIP Archive
.DESCRIPTION
Creates a ZIP Archive with all given Files (and subdirectories)
.PARAMETER Path
Input Path
.PARAMETER ArchiveName
Name of the archive to create.
.PARAMETER force
Enforce overwrite?
.PARAMETER fallback
Use Microsoft .NET Framework API instead of Compress-Archive (Bundled with PowerShell 5.0, or later)
.EXAMPLE
PS C:\> Out-ZipArchive -Path 'Value1' -ArchiveName 'Value2'
Creates a ZIP Archive with all given Files (and subdirectories)
.EXAMPLE
PS C:\> Out-ZipArchive -Path 'Value1' -ArchiveName 'Value2' -fallback
Creates a ZIP Archive with all given Files (and subdirectories) - Use .NET Framework API instead of Compress-Archive internal
.NOTES
We now use Compress-Archive by default. It is build upon the Microsoft .NET Framework API System.IO.Compression.ZipArchive and has the same limitation.
.LINK
Compress-Archive
.LINK
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.archive/compress-archive
#>
[CmdletBinding(ConfirmImpact = 'None')]
param
(
[Parameter(Mandatory = $true,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 0,
HelpMessage = 'Input Path')]
[ValidateNotNullOrEmpty()]
[Alias('Directory')]
[string]
$Path,
[Parameter(Mandatory = $true,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 1,
HelpMessage = 'Name of the archive to create')]
[ValidateNotNullOrEmpty()]
[Alias('FileName')]
[string]
$ArchiveName,
[Parameter(ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 2)]
[Alias('overwrite')]
[switch]
$force,
[Parameter(ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 3)]
[Alias('dotnet')]
[switch]
$fallback = $false
)
begin
{
$null = (Add-Type -AssemblyName System.IO.Compression.FileSystem)
$compressionLevel = [IO.Compression.CompressionLevel]::Optimal
Write-Verbose -Message "Compression level for $ArchiveName is $compressionLevel"
# Safe ProgressPreference and Setup SilentlyContinue for the function
$ExistingProgressPreference = ($ProgressPreference)
$ProgressPreference = 'SilentlyContinue'
}
process
{
if (-not $ArchiveName.EndsWith('.zip'))
{
Write-Verbose -Message "Bad filename detected $ArchiveName"
$ArchiveName += '.zip'
Write-Verbose -Message "Corrected filename is $ArchiveName"
}
if ($force)
{
if (Test-Path -Path $ArchiveName -ErrorAction SilentlyContinue -WarningAction SilentlyContinue)
{
Write-Verbose -Message "Overwrite old archive $ArchiveName"
try
{
$paramRemoveItem = @{
Path = $ArchiveName
Force = $true
Confirm = $false
ErrorAction = 'Stop'
WarningAction = 'Continue'
}
$null = (Remove-Item @paramRemoveItem)
}
catch
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# Retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# Output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
Write-Error -Message ($info.Exception) -TargetObject ($info.Target) -ErrorAction Stop
break
}
}
}
try
{
Write-Verbose -Message "Try to create archive $ArchiveName"
if ($fallback)
{
Write-Verbose -Message 'Run in fallback mode and using System.IO.Compression.ZipArchive instead of Compress-Archive'
$zip = ([IO.Compression.ZipFile]::CreateFromDirectory($Path, $ArchiveName, $compressionLevel, $false))
# And always make sure to close the locks on that file
$zip.Dispose()
}
else
{
$paramCompressArchive = @{
Path = $Path
CompressionLevel = $compressionLevel
DestinationPath = $ArchiveName
Force = $true
Confirm = $false
ErrorAction = 'Stop'
WarningAction = 'SilentlyContinue'
}
$null = (Compress-Archive @paramCompressArchive)
}
Write-Verbose -Message "Archive $ArchiveName was created"
}
catch
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# Retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# Output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
Write-Error -Message ($info.Exception) -TargetObject ($info.Target) -ErrorAction Stop
break
}
}
end
{
# Restore ProgressPreference
$ProgressPreference = $ExistingProgressPreference
Write-Verbose -Message 'Out-ZipArchive done'
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,245 @@
function Publish-BitbucketDownload
{
<#
.SYNOPSIS
Upload given file to BitBucket cloud service downloads section.
.DESCRIPTION
Upload given file to BitBucket cloud service downloads section.
I use this to upload build artifacts to the BitBucket Download section.
The code might not be perfect, and we still use the AUTH Header instead of OAuth yet,
but I needed a quick and dirty solution to get things going.
I might change a few things soon, but for now; this function is doing what it should.
.PARAMETER username
BitBucket cloud username, as plain text
.PARAMETER password
BitBucket cloud password, as plain text
.PARAMETER FilePath
File to upload, full path needed
.PARAMETER team
BitBucket cloud team aka username (Might not be the login username!!!)
.PARAMETER Project
BitBucket cloud project name
.EXAMPLE
PS ~> Publish-BitbucketDownload -username 'MyUsername' -password 'MySectretPassword' -FilePath 'Y:\dev\release\myproject-current.zip' -team 'dummyTeam' -Project 'myproject'
# Upload the artifact 'Y:\dev\release\myproject-current.zip' to the Download sections of the 'myproject' project of the 'dummyTeam', It uses User name and password (Both in plain ASC) to authenticate. However, both are converted to base64 to prevent any clear text header transfers.
.EXAMPLE
PS ~> Publish-BitbucketDownload -username 'MyUsername' -password 'MySectretPassword' -FilePath 'Y:\dev\release\myproject.nuget' -team 'dummyTeam' -Project 'myproject'
# Upload the artifact 'Y:\dev\release\myproject.nuget' to the Download sections of the 'myproject' project of the 'dummyTeam', It uses Username and password (Both in plain ASC) to authenticate. However, both are converted to base64 to prevent any clear text header transfers.
.NOTES
I created this because I did not have CURL installed on my build system.
With Curl this is an absolute no brainer:
curl -X POST "https://MyUsername:MySectretPassword@api.bitbucket.org/2.0/repositories/dummyTeam/myproject/downloads" --form files=@"/home/dev/release\myproject-current.zip"
INFO: Max. CPU: 16 % Max. Memory: 28.48 MB
TODO: Convert the request to use OAuth ASAP
#>
[CmdletBinding()]
param
(
[Parameter(Mandatory,
ValueFromPipeline,
HelpMessage = 'BitBucket cloud username, as plain text')]
[ValidateNotNullOrEmpty()]
[Alias('user')]
[string]
$username,
[Parameter(Mandatory,
ValueFromPipeline,
HelpMessage = 'BitBucket cloud password, as plain text')]
[ValidateNotNullOrEmpty()]
[Alias('pass')]
[string]
$password,
[Parameter(Mandatory,
ValueFromPipeline,
HelpMessage = 'File to upload, full path needed')]
[ValidateNotNullOrEmpty()]
[string]
$FilePath,
[Parameter(Mandatory,
ValueFromPipeline,
HelpMessage = 'BitBucket cloud team name')]
[ValidateNotNullOrEmpty()]
[string]
$team,
[Parameter(Mandatory,
ValueFromPipeline,
HelpMessage = 'BitBucket cloud project name')]
[ValidateNotNullOrEmpty()]
[Alias('ProjectName')]
[string]
$Project
)
process
{
# Build the URI for our request
$URI = 'https://api.bitbucket.org/2.0/repositories/' + $team + '/' + $Project + '/downloads'
# Create our authentication header
# TODO: Migrate to OAUTH
$pair = ($username + ':' + $password)
$encodedCreds = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($pair))
$basicAuthValue = ('Basic {0}' -f $encodedCreds)
$Headers = @{
Authorization = $basicAuthValue
}
# Cleanup the plain text stuff
$pair = $null
$encodedCreds = $null
# The boundary is essential - Trust me, very essential
$boundary = [Guid]::NewGuid().ToString()
<#
This is the crappy part: Build a body for a multipart request with PowerShell
This is something that should be changed in PowerShell ASAP (I mean it is really crappy and really bad).
It is an absolute no brainer with Curl.
#>
$bodyStart = @"
--$boundary
Content-Disposition: form-data; name="token"
--$boundary
Content-Disposition: form-data; name="files"; filename="$(Split-Path -Leaf -Path $FilePath)"
Content-Type: application/octet-stream
"@
# Generate the end of the request body to finish it.
$bodyEnd = @"
--$boundary--
"@
# Now we create a temp file (Another crappy/bad thing)
$requestInFile = (Join-Path -Path $env:TEMP -ChildPath ([IO.Path]::GetRandomFileName()))
try
{
# Create a new object for the brand new temporary file
$fileStream = (New-Object -TypeName 'System.IO.FileStream' -ArgumentList ($requestInFile, [IO.FileMode]'Create', [IO.FileAccess]'Write'))
try
{
# The Body start
$bytes = [Text.Encoding]::UTF8.GetBytes($bodyStart)
$fileStream.Write($bytes, 0, $bytes.Length)
# The original File
$bytes = [IO.File]::ReadAllBytes($FilePath)
$fileStream.Write($bytes, 0, $bytes.Length)
# Append the end of the body part
$bytes = [Text.Encoding]::UTF8.GetBytes($bodyEnd)
$fileStream.Write($bytes, 0, $bytes.Length)
}
finally
{
# End the Stream to close the file
$fileStream.Close()
# Cleanup
$fileStream = $null
# PowerShell garbage collector
[GC]::Collect()
}
# Make it multipart, this is the magic part...
$contentType = 'multipart/form-data; boundary={0}' -f $boundary
<#
The request itself is simple and easy, also works fine with Invoke-WebRequest instead of Invoke-RestMethod
I use Microsoft.PowerShell.Utility\Invoke-RestMethod to make sure the build in (Windows PowerShell native) function is used.
If PowerShell Core is installed or any Module provides a tweaked version... Just in case!
#>
try
{
$null = (Microsoft.PowerShell.Utility\Invoke-RestMethod -Uri $URI -Method Post -InFile $requestInFile -ContentType $contentType -Headers $Headers -ErrorAction Stop -WarningAction SilentlyContinue)
}
catch
{
# Remove the temp file
$null = (Remove-Item -Path $requestInFile -Force -Confirm:$false)
# Cleanup
$contentType = $null
# PowerShell garbage collector
[GC]::Collect()
# For the Build logs (will not break the build)
Write-Warning -Message 'StatusCode:' $_.Exception.Response.StatusCode.value__
Write-Warning -Message 'StatusDescription:' $_.Exception.Response.StatusDescription
# Saved in the verbose logs for this build
Write-Verbose -Message $_
# Inform the build and terminate (Will break the build)
Write-Error -Message 'We were unable to upload your file to the BitBucket downloads section, please check the build logs for further information.' -ErrorAction Stop
}
}
finally
{
# Remove the temp file
$null = (Remove-Item -Path $requestInFile -Force -Confirm:$false)
# Cleanup
$contentType = $null
# PowerShell garbage collector
[GC]::Collect()
}
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,211 @@
function Remove-FileEndingBlankLines
{
<#
.SYNOPSIS
Strip white space/blank lines from end of file or path
.DESCRIPTION
Strip white space/blank lines from end of file or path
.PARAMETER Path
Single File or Path you want to unclutter. (Mandatory)
.PARAMETER Recurse
Recurse through all subdirectories of the path provided. The default is not work recursively (Optional)
.PARAMETER noNewLine
No new (blank) line at the end of a file.
.PARAMETER SafeFilesOnly
Only safe files were processed. This is the default! This will prevent any issues with Binary Files or any other non safe to process files. If you like to process all files (can be dangerous) just negate this by using -SafeFilesOnly:$false
.EXAMPLE
PS C:\> Remove-FileEndingBlankLines -Path 'C:\Temp\Export-DistributionGroup2Cloud.ps1'
Strip white space/blank lines from end of 'C:\Temp\Export-DistributionGroup2Cloud.ps1'
.EXAMPLE
PS C:\> Remove-FileEndingBlankLines -Path 'C:\Temp\Export-DistributionGroup2Cloud.ps1'
Strip white space/blank lines from end of 'C:\Temp\Export-DistributionGroup2Cloud.ps1' without ending a final blank line at the end.
NOTE: Set-Content adds a final blank line by default. this switch prevents this!
.EXAMPLE
PS C:\> Remove-FileEndingBlankLines -Path 'C:\Temp' -Recurse
Strip white space/blank lines from end of files found in 'C:\Temp' and below (recursively).
.EXAMPLE
PS C:\> Remove-FileEndingBlankLines -Path 'C:\Temp' -Recurse -SafeFilesOnly:$false
Strip white space/blank lines from end of all files found in 'C:\Temp' and below (recursively).
This might be risky and/or even dangerous! If you process any binary files, they might be corrupt afterwards.
.NOTES
I created this helper function to unclutter the file ends and white space/blank lines from files during my build process.
I prefer the way that Set-Content handles it: Add a single blank line at the end of each file. This is use to the fact, that I concatenate several files during a build process.
I also added a switch (noNewLine) to prevent this.
By default only PowerShell and Markdown Files are processed by this function
.LINK
Set-Content
.LINK
Get-Content
#>
[CmdletBinding(ConfirmImpact = 'Low',
SupportsShouldProcess)]
param
(
[Parameter(Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 1,
HelpMessage = 'Single File or Path you want to unclutter.')]
[ValidateNotNullOrEmpty()]
[Alias('FilePath')]
[string]
$Path,
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 2)]
[switch]
$Recurse = $false,
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 3)]
[switch]
$noNewLine = $false,
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 4)]
[switch]
$SafeFilesOnly = $true
)
begin
{
$paramGetChildItem = @{
Path = $Path
File = $true
}
if ($SafeFilesOnly)
{
Write-Verbose -Message 'Only safe files are processed'
$paramGetChildItem.Include = '*.psm1', '*.ps1', '*.psd1', '*.ps1xml', '*.md'
}
else
{
Write-Verbose -Message 'All are processed - Might be a bad idea!!!'
}
if ($Recurse)
{
Write-Verbose -Message 'Read the info recursively'
$paramGetChildItem.Recurse = $true
}
else
{
Write-Verbose -Message 'Read the info'
}
}
process
{
# Make sure only files are processed and get the minimal info
(Get-ChildItem @paramGetChildItem | Where-Object -FilterScript {
-not $_.PSIsContainer
} | Select-Object -ExpandProperty FullName) | ForEach-Object -Process {
Write-Verbose -Message ('Try to unclutter {0}' -f $_)
$UnclutteredText = (((Get-Content -Path $_ -Raw).TrimEnd()).ToString())
try
{
if ($noNewLine)
{
Write-Verbose -Message ('Try to unclutter {0} (no final new line)' -f $_)
$null = ([io.file]::WriteAllText($_.FullName, $UnclutteredText))
}
else
{
Write-Verbose -Message ('Try to unclutter {0}' -f $_)
$paramSetContent = @{
Path = $_
Value = $UnclutteredText
Force = $true
Confirm = $false
Encoding = 'UTF8'
ErrorAction = 'Stop'
WarningAction = 'Continue'
}
$null = (Set-Content @paramSetContent)
}
Write-Verbose -Message ('Uncluttered {0}' -f $_)
}
catch
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# Retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# Output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
Write-Error -Message ($info.Exception) -TargetObject ($info.Target) -ErrorAction Stop
break
}
}
}
end
{
Write-Verbose -Message 'Clear-FileEnding Done'
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,188 @@
function Remove-Signature
{
<#
.SYNOPSIS
Finds all signed PowerShell files removes any digital signatures attached to them.
.DESCRIPTION
Finds all signed PowerShell files removes any digital signatures attached to them.
Supported Filetypes are: psm1, ps1, psd1, and ps1xml - All other Files are ignored!
.PARAMETER Path
Single File or Path you want to parse for digital signatures. (Mandatory)
.PARAMETER Recurse
Recurse through all subdirectories of the path provided. The default is not work recursively (Optional)
.EXAMPLE
PS C:\> Remove-Signature -Path 'C:\Temp\Export-DistributionGroup2Cloud.ps1'
Removes all digital signatures from 'C:\Temp\Export-DistributionGroup2Cloud.ps1'
.EXAMPLE
PS C:\> Remove-Signature -Path 'C:\Temp' -Recurse
Removes all digital signatures from psm1, ps1, psd1, and ps1xml files found in 'C:\Temp' and below (recursively).
.NOTES
Based on the ideas and work of the original Authors: Adrian Rodriguez and Zachary Loeber
.LINK
http://www.the-little-things.net
.LINK
https://psrdrgz.github.io/RemoveAuthenticodeSignature/
#>
[CmdletBinding(ConfirmImpact = 'Low',
SupportsShouldProcess)]
param
(
[Parameter(Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 1,
HelpMessage = 'Single File or Path you want to parse for digital signatures.')]
[ValidateNotNullOrEmpty()]
[Alias('FilePath')]
[string]
$Path,
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 2)]
[switch]
$Recurse = $false
)
begin
{
$paramGetChildItem = @{
Path = $Path
File = $true
Include = '*.psm1', '*.ps1', '*.psd1', '*.ps1xml'
}
if ($Recurse)
{
Write-Verbose -Message 'Work recursively'
$paramGetChildItem.Recurse = $true
}
}
process
{
$FilesToProcess = (Get-ChildItem @paramGetChildItem)
$FilesToProcess | ForEach-Object -Process {
$SignatureStatus = (Get-AuthenticodeSignature -FilePath $_).Status
$ScriptFileFullName = $_.FullName
if ($SignatureStatus -ne 'NotSigned')
{
try
{
$paramGetContent = @{
Path = $ScriptFileFullName
ErrorAction = 'Stop'
WarningAction = 'Continue'
}
$Content = (Get-Content @paramGetContent)
$paramNewObject = @{
TypeName = 'System.Text.StringBuilder'
ErrorAction = 'Stop'
WarningAction = 'Continue'
}
$StringBuilder = (New-Object @paramNewObject)
foreach ($Line in $Content)
{
if ($Line -match '^# SIG # Begin signature block|^<!-- SIG # Begin signature block -->')
{
break
}
else
{
$null = $StringBuilder.AppendLine($Line)
}
}
if ($pscmdlet.ShouldProcess("$ScriptFileFullName"))
{
$paramSetContent = @{
Path = $ScriptFileFullName
Value = $StringBuilder.ToString()
Force = $true
Confirm = $false
Encoding = 'UTF8'
ErrorAction = 'Stop'
WarningAction = 'Continue'
}
$null = (Set-Content @paramSetContent)
Write-Verbose -Message ('Removed signature from {0}' -f $ScriptFileFullName)
}
}
catch
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# Retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# Output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
Write-Error -Message ($info.Exception) -TargetObject ($info.Target) -ErrorAction Stop
break
}
}
else
{
Write-Verbose -Message ('No signature found in {0}' -f $ScriptFileFullName)
}
}
}
end
{
Write-Verbose -Message 'Remove-Signature Done'
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,118 @@
function Resolve-DNSHost
{
<#
.SYNOPSIS
Resolve DNS hostname to IP and reverse
.DESCRIPTION
This function resolves DNS hostname to IP and the other way around (reverse)
.PARAMETER HostEntry
Hostname (Single, or multiple) to test.
.EXAMPLE
PS C:\> Resolve-DNSHost -HostEntry www.hochwald.net
HostName IPAddress
-------- ---------
www.hochwald.net {104.28.0.64, 104.28.1.64, 2606:4700:30::681c:140, 2606:4700:30::681c:40}
This function resolves DNS hostname to IP and the other way around (reverse)
.EXAMPLE
PS C:\> Resolve-DNSHost -HostEntry 'www.hochwald.net','autodiscover.hochwald.net'
HostName IPAddress
-------- ---------
www.hochwald.net {104.28.0.64, 104.28.1.64, 2606:4700:30::681c:140, 2606:4700:30::681c:40}
autodiscover.hochwald.net {40.101.88.8, 40.101.88.184, 52.97.151.104, 40.101.60.24...}
This function resolves DNS hostname to IP and the other way around (reverse)
.OUTPUTS
psobject
.NOTES
Refactored of Resolve-Host.Ps1 by @PrateekKumarSingh
.LINK
Original:
https://gist.github.com/PrateekKumarSingh/586f2d3d43f7e8cb07ce
.LINK
Dns Class (system.net.dns):
https://docs.microsoft.com/de-de/dotnet/api/system.net.dns
.INPUTS
String
#>
[CmdletBinding(ConfirmImpact = 'None')]
[OutputType([psobject])]
param
(
[Parameter(Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 0,
HelpMessage = 'Hostname (Single, or multiple) to test.')]
[ValidateNotNullOrEmpty()]
[String[]]
$HostEntry
)
begin
{
# Cleanup
$Obj = @()
$Object = @()
}
process
{
$HostEntry | ForEach-Object -Process {
$Obj += New-Object -TypeName psobject -Property @{
HostName = $_
IPAddress = $([Net.Dns]::gethostentry($_).AddressList.IPAddressToString)
}
}
# Append
$Object = ($Obj | Select-Object -Property Hostname, IPAddress)
}
end
{
# Dump to the console
$Object
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,133 @@
#requires -Version 3.0 -Modules NetSecurity -RunAsAdministrator
<#
.SYNOPSIS
Enable inbound ICMP (Ping) and Remote Desktop (RDP)
.DESCRIPTION
Enable inbound ICMP (Ping) and Remote Desktop (RDP).
Ping will be enabled for IPv4 and IPv6.
.PARAMETER RDPGroup
Enable the complete RDP Groups in the Windows Firewall?
This will enable more then just the basic requirements, use with care!!!
.EXAMPLE
PS C:\> .\Set-AllowPingAndRemoteDesktop.ps1
Enable inbound ICMP (Ping) and Remote Desktop (RDP)
.EXAMPLE
PS C:\> .\Set-AllowPingAndRemoteDesktop.ps1 -verbose
Enable inbound ICMP (Ping) and Remote Desktop (RDP) - verbose run
.EXAMPLE
PS C:\> .\Set-AllowPingAndRemoteDesktop.ps1 -WhatIf
Enable inbound ICMP (Ping) and Remote Desktop (RDP) - Dry run
.NOTES
Helper script I use to bootstrap servers
Run this elevated!!!
#>
[CmdletBinding(ConfirmImpact = 'Medium',
SupportsShouldProcess)]
param
(
[Parameter(ValueFromPipeline)]
[switch]
$RDPGroup
)
begin
{
# Splat the Set-ItemProperty parameters
$paramSetItemProperty = @{
Path = 'HKLM:\System\CurrentControlSet\Control\Terminal Server'
Name = 'fDenyTSConnections'
Value = 0
ErrorAction = 'Continue'
}
# Splat the Enable-NetFirewallRule parameters
$paramEnableNetFirewallRule = @{
Confirm = $false
ErrorAction = 'Continue'
}
}
process
{
# Support WhatIf (SupportsShouldProcess)
if ($pscmdlet.ShouldProcess('Registry Terminal Server', 'Modify'))
{
# Tweak the Registry for Remote Desktop connections
$null = (Set-ItemProperty @paramSetItemProperty)
}
# We avoid using $RDPGroup.IsPresent
if ($PSBoundParameters.ContainsKey('RDPGroup'))
{
if ($pscmdlet.ShouldProcess('Firewall Group for Remote Desktop', 'Enable'))
{
# Allow Remote Desktop (The Group)
$null = (Get-NetFirewallRule -DisplayGroup 'Remote Desktop' -ErrorAction SilentlyContinue | Where-Object {
$_.Enabled -ne $true
} | Enable-NetFirewallRule @paramEnableNetFirewallRule)
}
}
else
{
if ($pscmdlet.ShouldProcess('Firewall Rules for Remote Desktop', 'Enable'))
{
# Alternative Approach: Enable the minimum, not the Group
Get-NetFirewallRule -Name 'RemoteDesktop-UserMode-In-TCP' -ErrorAction SilentlyContinue | Where-Object {
$_.Enabled -ne $true
} | Enable-NetFirewallRule @paramEnableNetFirewallRule
Get-NetFirewallRule -DisplayName 'Remote Desktop - User Mode (TCP-In)' -ErrorAction SilentlyContinue | Where-Object {
$_.Enabled -ne $true
} | Enable-NetFirewallRule @paramEnableNetFirewallRule
}
}
if ($pscmdlet.ShouldProcess('Ping', 'Enable'))
{
# Allow Ping for IPv4 and IPv6
# NOTE: The wildcard (ICMPv?) will select both. Replace it with 4 or 6 to use just one of them
Get-NetFirewallRule -DisplayName 'File and Printer Sharing (Echo Request - ICMPv?-In)' -ErrorAction SilentlyContinue | Where-Object {
$_.Enabled -ne $true
} | Enable-NetFirewallRule @paramEnableNetFirewallRule
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,520 @@
<#
.SYNOPSIS
Change the Google Chrome config to some defaults
.DESCRIPTION
Change the Google Chrome config to some defaults.
Chromium or any other Chromium based browsers are not yet supported.
.PARAMETER Profile
Name of the Google Chrome Profile.
The default is Default
.EXAMPLE
PS C:\> .\Set-ChromeDefaultPreferences.ps1
Change the Google Chrome config to some defaults.
We use the default profile (Default)
.EXAMPLE
PS C:\> .\Set-ChromeDefaultPreferences.ps1 -Profile 'Work'
Change the Google Chrome config to some defaults
We use the profile Work and not the default one
.NOTES
Chromium or any other Chromium based browsers are not yet supported.
I created this to tweak the existing Google Chrome configuration.
This is open-source software, if you find an issue try to fix it yourself.
There is no support and/or warranty in any kind
.LINK
http://www.enatec.io
.LINK
Get-Process
.LINK
Stop-Process
.LINK
ConvertFrom-Json
.LINK
Test-Path
.LINK
Get-Content
.LINK
Where-Object
.LINK
Add-Member
.LINK
ConvertTo-Json
.LINK
Set-Content
#>
[CmdletBinding(ConfirmImpact = 'Low')]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[AllowEmptyCollection()]
[AllowEmptyString()]
[AllowNull()]
[Alias('ChromeProfile', 'ChromeProfileName', 'ProfileName')]
[string]
$Profile = 'Default'
)
begin
{
#region Cleanup
$NewConfig = $null
$ChromePreferencesValues = $null
$DefaultConfigValues = $null
$Property = $null
#endregion Cleanup
#region Defaults
if ($Profile)
{
# We have an command line parameter, so we use this
$ChromeProfile = $Profile
}
else
{
# We do NOT have an command line parameter, so we add a default
$ChromeProfile = 'Default'
}
$Encoding = 'UTF8'
$STP = 'Stop'
# Create the new object
$NewConfig = @{
}
#endregion Defaults
#region PSEdition
if ($PSVersionTable.PSEdition -eq 'Desktop')
{
# Desktop Edition - Windows
$BaseChromeProfilePath = "$env:LOCALAPPDATA\Google\Chrome\User Data\"
#region KillChrome
#region Splat
$paramGetProcess = @{
Name = 'chrome'
ErrorAction = 'SilentlyContinue'
}
$paramStopProcess = @{
Force = $true
ErrorAction = 'SilentlyContinue'
}
#endregion Splat
# Kill Chrome
$null = (Get-Process @paramGetProcess | Stop-Process @paramStopProcess)
#endregion KillChrome
}
elseif ($PSVersionTable.PSEdition -eq 'Core')
{
#region PowerShellCoreHandling
if ($IsLinux -eq $true)
{
# Core Edition - Linux/Unix
#region Splat
$paramWriteWarning = @{
Message = 'PowerShell Core on Linux/Unix is not yet tested or supported'
}
#endregion Splat
Write-Warning @paramWriteWarning
#region Splat
$paramWriteError = @{
Message = 'Sorry, Linux is not yet supüported'
Category = 'OperationStopped'
ErrorAction = $STP
}
#endregion Splat
Write-Error @paramWriteError
}
elseif ($IsMacOS -eq $true)
{
# Core Edition - macOS or Mac OSX
$BaseChromeProfilePath = "$env:HOME/Library/Application Support/Google/Chrome/"
#region KillChrome
#region Splat
$paramGetProcess = @{
Name = 'Google Chrome*'
ErrorAction = 'SilentlyContinue'
}
$paramStopProcess = @{
Force = $true
ErrorAction = 'SilentlyContinue'
}
#endregion Splat
# Kill Chrome
$null = (Get-Process @paramGetProcess | Stop-Process @paramStopProcess)
#endregion KillChrome
}
elseif ($IsWindows -eq $true)
{
# Core Edition - Windows
$BaseChromeProfilePath = "$env:LOCALAPPDATA\Google\Chrome\User Data\"
}
else
{
#region Splat
$paramWriteError = @{
Message = 'Unknown PowerShell Core installation'
Category = 'NotEnabled'
ErrorAction = $STP
}
#endregion Splat
Write-Error @paramWriteError
}
#endregion PowerShellCoreHandling
}
else
{
#region Splat
$paramWriteError = @{
Message = 'Unknown PowerShell Edition'
Category = 'InvalidOperation'
ErrorAction = $STP
}
#endregion Splat
Write-Error @paramWriteError
}
#endregion PSEdition
#region DefaultConfig
#region DefaultConfigJson
<#
Could be an external file, but embedded is easier to handle.
Looks crappy, but it works fine!
#>
$DefaultConfigJson = '{
"credentials_enable_autosignin": false,
"credentials_enable_service": false,
"enable_do_not_track": true,
"default_apps": "noinstall",
"alternate_error_pages": {
"enabled": false
},
"distribution": {
"import_bookmarks": false,
"make_chrome_default": false,
"make_chrome_default_for_user": false,
"verbose_logging": true,
"skip_first_run_ui": true,
"create_all_shortcuts": true,
"suppress_first_run_default_browser_prompt": true
},
"autofill": {
"enabled": false,
"credit_card_enabled": false,
"profile_enabled": false,
"use_mac_address_book": false
},
"bookmark_bar": {
"show_apps_shortcut": false,
"show_on_all_tabs": true
},
"browser": {
"show_home_button": true,
"has_seen_welcome_page": true,
"check_default_browser": false
},
"custom_handlers": {
"enabled": false,
"ignored_protocol_handlers": [],
"registered_protocol_handlers": []
},
"intl": {
"accept_languages": "en-US,en,de-DE,de"
},
"net": {
"network_prediction_options": 2
},
"profile": {
"block_third_party_cookies": false,
"password_manager_enabled": false,
"default_content_setting_values": {
"geolocation": 1,
"media_stream_camera": 2,
"media_stream_mic": 2,
"notifications": 2,
"plugins": 2,
"popups": 2,
"ppapi_broker": 2,
"midi_sysex": 2,
"payment_handler": 2
}
},
"safebrowsing": {
"enabled": true,
"scout_reporting_enabled": false
},
"search": {
"suggest_enabled": false
},
"signin": {
"allowed": false,
"allowed_on_next_startup": false
},
"spellcheck": {
"use_spelling_service": false
},
"tranSplate": {
"enabled": false
},
"tranSplate_blocked_languages": [
"en",
"de"
],
"dns_prefetching": {
"enabled": false
},
"payments": {
"can_make_payment_enabled": false
},
"webkit": {
"webprefs": {
"tabs_to_links": true
}
}
}'
#endregion DefaultConfigJson
#region Splat
$paramConvertFromJson = @{
InputObject = $DefaultConfigJson
ErrorAction = $STP
}
#endregion Splat
# The real work: Import the embedded JSON Data
$DefaultConfig = (ConvertFrom-Json @paramConvertFromJson)
#endregion DefaultConfig
}
process
{
#region ExistingConfig
#region Splat
$paramTestPath = @{
Path = ($BaseChromeProfilePath + $ChromeProfile + '\Preferences')
ErrorAction = 'SilentlyContinue'
}
#endregion Splat
if (Test-Path @paramTestPath)
{
# Import the existing config
try
{
#region Splat
$paramGetContent = @{
Path = ($BaseChromeProfilePath + $ChromeProfile + '\Preferences')
Raw = $true
ErrorAction = $STP
Encoding = $Encoding
Force = $true
}
$paramConvertFromJson = @{
InputObject = (Get-Content @paramGetContent )
ErrorAction = $STP
}
#endregion Splat
# The real work: Import the JSON Data
$ChromePreferences = (ConvertFrom-Json @paramConvertFromJson)
}
catch
{
#region Splat
$paramWriteError = @{
Message = 'Unable to load the configuration file'
Category = 'ReadError'
ErrorAction = $STP
}
#endregion Splat
Write-Error @paramWriteError
}
}
else
{
<#
No existing config found
Create en empty object
#>
$ChromePreferences = @{
}
}
#endregion ExistingConfig
#region ValueVariables
# The existing configuration
$ChromePreferencesValues = ($ChromePreferences.psobject.Properties | Where-Object -FilterScript {
$_.MemberType -eq 'NoteProperty'
})
# The recommended configuration
$DefaultConfigValues = ($DefaultConfig.psobject.Properties | Where-Object -FilterScript {
$_.MemberType -eq 'NoteProperty'
})
#endregion ValueVariables
#region RecommendedValues
# Fill in the new Defaults
foreach ($Property in $DefaultConfigValues)
{
try
{
#region Splat
$paramAddMember = @{
MemberType = 'NoteProperty'
Name = $Property.Name
Value = $Property.Value
ErrorAction = $STP
}
#endregion Splat
# Add the configuration value
$null = ($NewConfig | Add-Member @paramAddMember)
}
catch
{
#region Splat
$paramWriteWarning = @{
Message = ('Unable to set recommended value for {0}' -f $Property.Name)
}
#endregion Splat
Write-Warning @paramWriteWarning
}
}
#endregion RecommendedValues
#region ExistingValues
# Add the old config values
foreach ($Property in $ChromePreferencesValues)
{
try
{
#region Splat
$paramAddMember = @{
MemberType = 'NoteProperty'
Name = $Property.Name
Value = $Property.Value
ErrorAction = $STP
}
#endregion Splat
# Add the configuration value
$null = ($NewConfig | Add-Member @paramAddMember)
}
catch
{
#region Splat
$paramWriteVerbose = @{
Message = ('The value of {0} was replaced' -f $Property.Name)
}
#endregion Splat
Write-Verbose @paramWriteVerbose
}
}
#endregion ExistingValues
}
end
{
if ($pscmdlet.ShouldProcess(($BaseChromeProfilePath + $ChromeProfile + '\Preferences'), 'Save'))
{
#region SaveTheNewPreferences
# Save the Preferences
try
{
#region Splat
$paramConvertToJson = @{
Depth = 100
Compress = $true
}
$paramSetContent = @{
Path = ($BaseChromeProfilePath + $ChromeProfile + '\Preferences')
Value = ($NewConfig | ConvertTo-Json @paramConvertToJson )
Force = $true
Encoding = $Encoding
ErrorAction = $STP
}
#endregion Splat
# Save the new Chrome configuration file
$null = (Set-Content @paramSetContent)
}
catch
{
#region Splat
$paramWriteError = @{
Message = 'Unable to save the new configuration file'
Category = 'WriteError'
ErrorAction = $STP
}
#endregion Splat
Write-Error @paramWriteError
}
#endregion SaveTheNewPreferences
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,347 @@
function Set-IPv6InWindows
{
<#
.SYNOPSIS
Configuring the IPv6 value in windows the registry
.DESCRIPTION
Configuring the IPv6 value in windows the registry
Based on the Microsoft Information, Microsoft KB929852, RFC 3484, and RFC 4291
.PARAMETER Force
Forces the cmdlet to set a property on items that cannot otherwise be accessed by the user.
.PARAMETER Value
Specifies the value of the property.
.EXAMPLE
PS C:\> Set-IPv6InWindows -Value 0 -WhatIf
Enable all IPv6 components
.EXAMPLE
PS C:\> Set-IPv6InWindows -Value 32 -verbose
Prefer IPv4 over IPv6 will be set, with a verbose output
.LINK
Get-IPv6InWindows
.LINK
https://docs.microsoft.com/en-us/troubleshoot/windows-server/networking/configure-ipv6-in-windows
.LINK
https://docs.microsoft.com/en-us/troubleshoot/windows-server/networking/configure-ipv6-in-windows#reference
.NOTES
Next version might also support test inputs instead of the numbers (Dec).
This is just a quick and dirty initial version!
Want to knwo what is set in your registry? Use its companion Get-IPv6InWindows
#>
[CmdletBinding(ConfirmImpact = 'Medium',
SupportsShouldProcess)]
[OutputType([string])]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
[ValidateSet('32', '17', '16', '1', '10', '8', '4', '2', '255', '0')]
[Alias('IPv6Configuration', 'IPv6Config')]
[int]
$Value = 0,
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[switch]
$Force
)
begin
{
#region BoundParameters
if (($PSCmdlet.MyInvocation.BoundParameters['Force']).IsPresent)
{
$IsForced = $true
}
else
{
$IsForced = $false
}
if (($PSCmdlet.MyInvocation.BoundParameters['Verbose']).IsPresent)
{
$IsVerbose = $true
}
else
{
$IsVerbose = $false
}
if (($PSCmdlet.MyInvocation.BoundParameters['Debug']).IsPresent)
{
$IsDebug = $true
}
else
{
$IsDebug = $false
}
#endregion BoundParameters
#region ValueSwitch
switch ($Value)
{
0
{
$ValueText = ('Enable all IPv6 components ({0})' -f $Value)
}
255
{
$ValueText = ('Disable all IPv6 components ({0})' -f $Value)
Write-Warning -Message 'This is not recommended, Think about 32 (Prefer IPv4 over IPv6) instead.'
}
2
{
$ValueText = ('Disable 6to4 ({0})' -f $Value)
}
4
{
$ValueText = ('Disable ISATAP ({0})' -f $Value)
}
8
{
$ValueText = ('Disable Teredo ({0})' -f $Value)
}
10
{
$ValueText = ('Disable Teredo and 6to4 ({0})' -f $Value)
}
1
{
$ValueText = ('Disable all tunnel interfaces ({0})' -f $Value)
}
16
{
$ValueText = ('Disable all LAN and PPP interfaces ({0})' -f $Value)
}
17
{
$ValueText = ('Disable all LAN, PPP and tunnel interfaces ({0})' -f $Value)
}
32
{
$ValueText = ('Prefer IPv4 over IPv6 ({0})' -f $Value)
}
default
{
$paramWriteError = @{
Exception = ('Unknown value found: {0}' -f $Value)
Message = ('Sorry, but this cmdlet does NOT support the value {0}' -f $Value)
Category = 'OperationStopped'
CategoryActivity = 'Please check the supported values'
TargetObject = $Value
ErrorAction = 'Stop'
}
Write-Error @paramWriteError
# Only here to catch a global ErrorAction overwrite
exit 1
}
}
Write-Verbose -Message ('New IPv6 configuration: {0}' -f $ValueText)
#endregion ValueSwitch
# Get the Value from the registry
$paramGetItemProperty = @{
Path = 'HKLM:\SYSTEM\CurrentControlSet\Services\tcpip6\Parameters'
Name = 'DisabledComponents'
Debug = $IsDebug
Verbose = $IsVerbose
ErrorAction = 'Continue'
WarningAction = 'Continue'
}
$ComponentValue = (Get-ItemProperty @paramGetItemProperty | Select-Object -ExpandProperty DisabledComponents)
if ($Value -eq $ComponentValue)
{
# Don't go any further!
$paramWriteError = @{
Exception = 'Old an new value are the same'
Message = 'The new value matches the existing IPv6 configuration!'
Category = 'OperationStopped'
CategoryActivity = 'No further action is required'
TargetObject = $Value
ErrorAction = 'Stop'
}
Write-Error @paramWriteError
# Only here to catch a global ErrorAction overwrite
exit 1
}
#region
switch ($ComponentValue)
{
0
{
$ComponentValueText = ('All IPv6 components are enabled ({0})' -f $ComponentValue)
}
255
{
$ComponentValueText = ('All IPv6 components are disabled ({0})' -f $ComponentValue)
}
2
{
$ComponentValueText = ('6to4 is disabled ({0})' -f $ComponentValue)
}
4
{
$ComponentValueText = ('ISATAP is disabled ({0})' -f $ComponentValue)
}
8
{
$ComponentValueText = ('Teredo is disabled ({0})' -f $ComponentValue)
}
10
{
$ComponentValueText = ('Teredo and 6to4 is disabled ({0})' -f $ComponentValue)
}
1
{
$ComponentValueText = ('All tunnel interfaces are disabled ({0})' -f $ComponentValue)
}
16
{
$ComponentValueText = ('All LAN and PPP interfaces are disabled ({0})' -f $ComponentValue)
}
17
{
$ComponentValueText = ('All LAN, PPP and tunnel interfaces are disabled ({0})' -f $ComponentValue)
}
32
{
$ComponentValueText = ('Prefer IPv4 over IPv6 ({0})' -f $ComponentValue)
}
default
{
$ComponentValueText = ('Unknown value found: {0}' -f $ComponentValue)
Write-Warning -Message $ComponentValueText
}
}
Write-Verbose -Message ('Existing IPv6 configuration: {0}' -f $ComponentValueText)
#endregion
}
process
{
if ($PSCmdlet.ShouldProcess('Existing IPv6 configuration', 'modify'))
{
try
{
$paramSetItemProperty = @{
Path = 'HKLM:\SYSTEM\CurrentControlSet\Services\tcpip6\Parameters'
Name = 'DisabledComponents'
Value = $Value
Force = $IsForced
Debug = $IsDebug
Verbose = $IsVerbose
Confirm = $false
ErrorAction = 'Stop'
WarningAction = 'Continue'
}
$null = (Set-ItemProperty @paramSetItemProperty)
}
catch
{
#region ErrorHandler
# get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
Write-Verbose -Message $info
Write-Error -Message ($info.Exception) -ErrorAction Stop
# Only here to catch a global ErrorAction overwrite
exit 1
#endregion ErrorHandler
}
# Get the Value from the registry
$ComponentValue = $null
$paramGetItemProperty = @{
Path = 'HKLM:\SYSTEM\CurrentControlSet\Services\tcpip6\Parameters'
Name = 'DisabledComponents'
Debug = $IsDebug
Verbose = $IsVerbose
ErrorAction = 'Continue'
WarningAction = 'Continue'
}
$ComponentValue = (Get-ItemProperty @paramGetItemProperty | Select-Object -ExpandProperty DisabledComponents)
if ($Value -eq $ComponentValue)
{
Write-Verbose -Message 'New IPv6 configuration was applied'
}
else
{
# Don't go any further!
$paramWriteError = @{
Exception = 'Unable to apply IPv6 configuration'
Message = ('New IPv6 configuration was NOT applied! You requested {0}, but the set is {1}' -f $ValueText, $ComponentValue)
Category = 'OperationStopped'
CategoryActivity = 'Please check the registry and your permissions'
TargetObject = $Value
ErrorAction = 'Stop'
}
Write-Error @paramWriteError
# Only here to catch a global ErrorAction overwrite
exit 1
}
}
}
end
{
('New IPv6 configuration is set to: {0}' -f $ValueText)
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,114 @@
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Set the Windows Power Plan to High Performance
.DESCRIPTION
Set the Windows Power Plan to High Performance, it also disables Hibernation and System Standby
.EXAMPLE
PS C:\> .\Set-PowerPlanToHighPerformance.ps1
.NOTES
Works fine on Windows Server 2016 (Developed for server use).
Should also work on Windows 10, but I never tested it on a Windows 10 system!
#>
[CmdletBinding(ConfirmImpact = 'Low')]
param ()
process
{
#region Cleanup
$ActivePowerPlan = $null
$PowerPlanHighPowerState = $null
#endregion Cleanup
#region InformationGathering
# Splat the parameters
$paramGetWmiObject = @{
Namespace = 'root\cimv2\power'
Class = 'Win32_PowerPlan'
}
# Gather the PowerPlan information
$ActivePowerPlan = (Get-WmiObject @paramGetWmiObject | Select-Object -Property ElementName, IsActive)
# Filter the 'High Performance' plan info
$PowerPlanHighPowerState = $ActivePowerPlan | Where-Object -FilterScript {
$_.ElementName -eq 'High Performance'
}
#endregion InformationGathering
#region CheckIfTheTweakIsNeeded
if ($PowerPlanHighPowerState.IsActive -ne $true)
{
# Use the PowerPlan "High Performance"
$paramGetWmiObject.Filter = "ElementName = 'High Performance'"
$powerPlan = (Get-WmiObject @paramGetWmiObject)
#region ActivateThePowerPlan
$null = (Invoke-Command -ScriptBlock {
$powerPlan.Activate()
} -ErrorAction SilentlyContinue)
<#
This looks a bit crappy, but it works fine and I don't like to have any output of the activation
#>
#endregion ActivateThePowerPlan
}
#endregion CheckIfTheTweakIsNeeded
#region Cleanup
$PowerPlanHighPowerState = $null
#endregion Cleanup
#region Retest
$PowerPlanHighPowerState = $ActivePowerPlan | Where-Object -FilterScript {
$_.ElementName -eq 'High Performance'
}
# Filter the 'High Performance' plan info
if ($PowerPlanHighPowerState.IsActive -ne $true)
{
Write-Warning -Message "Unable to set the PowerPlan to 'High Performance'"
}
#endregion Retest
#region NoStandBy
& "$env:windir\system32\powercfg.cpl" -change -standby-timeout-ac 0
#endregion NoStandBy
#region DisableHibernationSupport
& "$env:windir\system32\powercfg.cpl" -change -hibernate-timeout-ac 0
#endregion DisableHibernationSupport
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,117 @@
function Set-PublishUserActivities
{
<#
.SYNOPSIS
Enable or Disable the collection of Activity History
.DESCRIPTION
Enable or Disable the collection of Activity History in Windows 10. The default is to disable it!
.PARAMETER enable
Enable the collection of Activity History in Windows 10
.EXAMPLE
PS C:\> Set-PublishUserActivities
Disable the collection of Activity History in Windows 10
.EXAMPLE
PS C:\> Set-PublishUserActivities -enable
Enable the collection of Activity History in Windows 10
.NOTES
Quick and dirty function
.LINK
https://lifehacker.com/windows-10-collects-activity-data-even-when-tracking-is-1831054394
.LINK
https://www.tenforums.com/tutorials/100341-enable-disable-collect-activity-history-windows-10-a.html#option2s2
#>
[CmdletBinding(ConfirmImpact = 'None',
SupportsShouldProcess)]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 1)]
[switch]
$enable = $false
)
begin
{
$RegistryPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\System'
$RegistryName = 'PublishUserActivities'
if ($enable)
{
$RegistryValue = '1'
$SetAction = 'Enable'
Write-Verbose -Message 'Enable the collection of Activity History'
}
else
{
$RegistryValue = '0'
$SetAction = 'Disable'
Write-Verbose -Message 'Disable the collection of Activity History'
}
}
process
{
if ($pscmdlet.ShouldProcess('Collection of Activity History', $SetAction))
{
try
{
$SetPublishUserActivitiesParams = @{
Path = $RegistryPath
Name = $RegistryName
Value = $RegistryValue
PropertyType = 'DWORD'
Force = $true
Confirm = $false
ErrorAction = 'Stop'
WarningAction = 'SilentlyContinue'
}
$null = (New-ItemProperty @SetPublishUserActivitiesParams)
Write-Verbose -Message 'Collection of Activity History value modified.'
}
catch
{
Write-Warning -Message 'Unable to modify the collection of Activity History value!'
}
}
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,91 @@
function Test-IsAdmin
{
<#
.SYNOPSIS
Check if PowerShell run elevated (e.g. as admin or not)
.DESCRIPTION
This is a complete new approach to check if the Shell runs elevated or not.
It runs on PowerShell and PowerShell Core, and it supports macOS or Linux as well.
.EXAMPLE
PS C:\> Test-IsAdmin
.NOTES
Rewritten function to support PowerShell Desktop and Core on Windows, macOS, and Linux
Mostly used within other functions and in the personal PowerShell profiles.
Releasenotes:
1.0.1 2019-05-09: Add some comments to the code
1.0.0 2019-05-09: Initial Release of the rewritten function
THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
#>
[CmdletBinding(ConfirmImpact = 'None')]
[OutputType([bool])]
param ()
process
{
if ($PSVersionTable.PSEdition -eq 'Desktop')
{
# Fastest way on Windows
([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')
}
elseif (($PSVersionTable.PSEdition -eq 'Core') -and ($PSVersionTable.Platform -eq 'Unix'))
{
# Ok, on macOS and Linux we use ID to figure out if we run elevated (0 means superuser rights)
if ((id -u) -eq 0)
{
return $true
}
else
{
return $false
}
}
elseif (($PSVersionTable.PSEdition -eq 'Core') -and ($PSVersionTable.Platform -eq 'Win32NT'))
{
# For PowerShell Core on Windows the same approach as with the Desktop work just fine
# This is for future improvements :-)
([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')
}
else
{
# Unable to figure it out!
Write-Warning -Message 'Unknown'
return
}
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,371 @@
function Test-Port
{
<#
.SYNOPSIS
Tests port on a given computer.
.DESCRIPTION
Tests port on computer. This functions supports both: TCP and UPD
.PARAMETER computer
Name of server to test the port connection on.
.PARAMETER port
Port to test
.PARAMETER tcp
Use tcp port
.PARAMETER udp
Use udp port
.PARAMETER UDPTimeOut
Sets a timeout for UDP port query. (In milliseconds, Default is 1000)
.PARAMETER TCPTimeOut
Sets a timeout for TCP port query. (In milliseconds, Default is 1000)
.EXAMPLE
Test-Port -computer 'server' -port 80
Checks port 80 on server 'server' to see if it is listening
.EXAMPLE
'server' | Test-Port -port 80
Checks port 80 on server 'server' to see if it is listening
.EXAMPLE
Test-Port -computer @("server1","server2") -port 80
Checks port 80 on server1 and server2 to see if it is listening
.EXAMPLE
Test-Port -computer dc1 -port 17 -udp -UDPtimeout 10000
Server : dc1
Port : 17
TypePort : UDP
Open : True
Notes : "My spelling is Wobbly. It's good spelling but it Wobbles, and the letters
get in the wrong places." A. A. Milne (1882-1958)
Description
-----------
Queries port 17 (qotd) on the UDP port and returns whether port is open or not
.EXAMPLE
@("server1","server2") | Test-Port -port 80
Checks port 80 on server1 and server2 to see if it is listening
.EXAMPLE
(Get-Content hosts.txt) | Test-Port -port 80
Checks port 80 on servers in host file to see if it is listening
.EXAMPLE
Test-Port -computer (Get-Content hosts.txt) -port 80
Checks port 80 on servers in host file to see if it is listening
.EXAMPLE
Test-Port -computer (Get-Content hosts.txt) -port @(1..59)
Checks a range of ports from 1-59 on all servers in the hosts.txt file
.NOTES
For TCP tests, you might want to use Test-NetConnection
But Test-NetConnection is unable to test UDP Ports
Author: Boe Prox
DateCreated: 18Aug2010
Contributor: Joerg Hochwald
.LINK
https://boeprox.wordpress.org
.LINK
http://jhochwald.com
.LINK
http://www.iana.org/assignments/port-numbers
#>
[cmdletbinding(
DefaultParameterSetName = '',
ConfirmImpact = 'None'
)]
param (
[Parameter(
Mandatory, HelpMessage = 'Name of server to test the port connection on.',
Position = 0,
ParameterSetName = '',
ValueFromPipeline)]
[array]
$computer,
[Parameter(
Position = 1, HelpMessage = 'Port to test',
Mandatory,
ParameterSetName = '')]
[array]
$port,
[Parameter(
ParameterSetName = '')]
[int]
$TCPtimeout = 1000,
[Parameter(
ParameterSetName = '')]
[int]
$UDPtimeout = 1000,
[Parameter(
ParameterSetName = '')]
[switch]
$TCP,
[Parameter(
ParameterSetName = '')]
[switch]
$UDP
)
begin
{
# Check if we test TCP or UDP
if ((-not $TCP) -AND (-not $UDP))
{
<#
Nothing? OK, we use the Defualt (TCP)
#>
$TCP = $True
}
<#
Typically you never do this, but in this case I felt it was for the benefit of the function as any errors will be noted in the output of the report
It also reduce the handling within the code. Smart, right?
#>
$ErrorActionPreference = 'SilentlyContinue'
# Cleanup
$report = @()
}
process
{
foreach ($c in $computer)
{
foreach ($p in $port)
{
if ($TCP)
{
# Create temporary holder
# TODO: Replace this
$temp = '' | Select-Object -Property Server, Port, TypePort, Open, Notes
# Create object for connecting to port on computer
$tcpobject = (New-Object -TypeName system.Net.Sockets.TcpClient)
# Connect to remote machine's port
$connect = $tcpobject.BeginConnect($c, $p, $null, $null)
# Configure a timeout before quitting
$wait = $connect.AsyncWaitHandle.WaitOne($TCPtimeout, $False)
# If timeout
if (-not $wait)
{
# Close connection
$tcpobject.Close()
Write-Verbose -Message 'Connection Timeout'
# Build report
$temp.Server = $c
$temp.Port = $p
$temp.TypePort = 'TCP'
$temp.Open = $False
$temp.Notes = 'Connection to Port Timed Out'
}
else
{
$error.Clear()
$null = $tcpobject.EndConnect($connect)
# If error
if ($error[0])
{
# Begin making error more readable in report
[string]$string = ($error[0].exception).message
$message = (($string.split(':')[1]).replace('"', '')).TrimStart()
$failed = $True
}
# Close connection
$tcpobject.Close()
# If unable to query port to due failure
if ($failed)
{
# Build report
$temp.Server = $c
$temp.Port = $p
$temp.TypePort = 'TCP'
$temp.Open = $False
$temp.Notes = "$message"
}
else
{
# Build report
$temp.Server = $c
$temp.Port = $p
$temp.TypePort = 'TCP'
$temp.Open = $True
$temp.Notes = ''
}
}
# Reset failed value
$failed = $null
# Merge temp array with report
$report += $temp
}
if ($UDP)
{
# Create temporary holder
$temp = '' | Select-Object -Property Server, Port, TypePort, Open, Notes
# Create object for connecting to port on computer
$udpobject = (New-Object -TypeName system.Net.Sockets.Udpclient)
# Set a timeout on receiving message
$udpobject.client.ReceiveTimeout = $UDPtimeout
# Connect to remote machine's port
Write-Verbose -Message 'Making UDP connection to remote server'
$udpobject.Connect("$c", $p)
# Sends a message to the host to which you have connected.
Write-Verbose -Message 'Sending message to remote host'
$a = (New-Object -TypeName system.text.asciiencoding)
$byte = $a.GetBytes("$(Get-Date)")
$null = $udpobject.Send($byte, $byte.length)
# IPEndPoint object will allow us to read datagrams sent from any source.
Write-Verbose -Message 'Creating remote endpoint'
$remoteendpoint = (New-Object -TypeName system.net.ipendpoint -ArgumentList ([ipaddress]::Any, 0))
try
{
# Blocks until a message returns on this socket from a remote host.
Write-Verbose -Message 'Waiting for message return'
$receivebytes = $udpobject.Receive([ref]$remoteendpoint)
[string]$returndata = $a.GetString($receivebytes)
if ($returndata)
{
Write-Verbose -Message 'Connection Successful'
# Build report
$temp.Server = $c
$temp.Port = $p
$temp.TypePort = 'UDP'
$temp.Open = $True
$temp.Notes = $returndata
$udpobject.close()
}
}
catch
{
if ($error[0].ToString() -match '\bRespond after a period of time\b')
{
# Close connection
$udpobject.Close()
# Make sure that the host is online and not a false positive that it is open
if (Test-Connection -ComputerName $c -Count 1 -Quiet)
{
Write-Verbose -Message 'Connection Open'
# Build report
$temp.Server = $c
$temp.Port = $p
$temp.TypePort = 'UDP'
$temp.Open = $True
$temp.Notes = ''
}
else
{
<#
It is possible that the host is not online or that the host is online,
but ICMP is blocked by a firewall and this port is actually open.
#>
Write-Verbose -Message 'Host maybe unavailable'
# Build report
$temp.Server = $c
$temp.Port = $p
$temp.TypePort = 'UDP'
$temp.Open = $False
$temp.Notes = 'Unable to verify if port is open or if host is unavailable.'
}
}
elseif ($error[0].ToString() -match 'forcibly closed by the remote host')
{
# Close connection
$udpobject.Close()
Write-Verbose -Message 'Connection Timeout'
# Build report
$temp.Server = $c
$temp.Port = $p
$temp.TypePort = 'UDP'
$temp.Open = $False
$temp.Notes = 'Connection to Port Timed Out'
}
else
{
$udpobject.close()
}
}
# Merge temp array with report
$report += $temp
}
}
}
}
end
{
# Generate Report
$report
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,78 @@
function Test-ValidEmail
{
<#
.SYNOPSIS
Simple Function to check if a String is a valid Mail
.DESCRIPTION
Simple Function to check if a String is a valid Mail and return a Bool
.PARAMETER address
Address String to Check
.OUTPUT
Bool
.INPUT
String
.EXAMPLE
# Not a valid String
PS C:\> Test-ValidEmail -address 'Joerg.Hochwald'
False
.EXAMPLE
# Valid String
PS C:\> Test-ValidEmail -address 'Joerg.Hochwald@outlook.com'
True
.NOTES
Disclaimer: The code is provided 'as is,' with all possible faults, defects or errors, and without warranty of any kind.
Author: Joerg Hochwald
#>
[OutputType([bool])]
param
(
[Parameter(Mandatory,
HelpMessage = 'Address String to Check')]
[ValidateNotNullOrEmpty()]
[string]
$address
)
process
{
($address -as [mailaddress]).Address -eq $address -and $address -ne $null
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,281 @@
#requires -Version 2.0 -Modules PowerShellGet -RunAsAdministrator
<#
.SYNOPSIS
Import/export all Modules installed from a repository
.DESCRIPTION
Import/export all Modules installed from a repository
The Import option itries to install the modules.
Perfect for clones of existing existing systems.
.PARAMETER Export
Export the List of Modules installed via given repository
.PARAMETER Import
Import the List and installs all Modules via given repository
.PARAMETER Path
File used to handle the Import/Export
.PARAMETER Repository
The repository to use. The default is the PowerShell Gallery
.EXAMPLE
PS C:\> .\Transfer_Repository_Installed_Modules.ps1 -Export -Path 'C:\Temp\list.txt'
.EXAMPLE
PS C:\> .\Transfer_Repository_Installed_Modules.ps1 -Export -Path 'C:\Temp\list.txt' -Repository 'Internal'
.EXAMPLE
PS C:\> .\Transfer_Repository_Installed_Modules.ps1 -Import -Path 'C:\Temp\list.txt'
.EXAMPLE
PS C:\> .\Transfer_Repository_Installed_Modules.ps1 -Import -Path 'C:\Temp\list.txt' -Repository 'Internal'
.NOTES
Releasenotes:
1.0.0 2019-03-07: Internal Release
1.0.1 2019-03-10: Initial Version with Repository Support
THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
Dependencies:
PowerShellGet
Elevated Shell
.LINK
https://aka.ms/InstallModule
#>
[CmdletBinding(DefaultParameterSetName = 'Import',
ConfirmImpact = 'None')]
param
(
[Parameter(ParameterSetName = 'Export',
ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 0)]
[switch]
$Export,
[Parameter(ParameterSetName = 'Import',
ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 0)]
[switch]
$Import,
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 1)]
[ValidateNotNullOrEmpty()]
[string]
$Path = 'C:\Tools\list.txt',
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 2)]
[ValidateNotNullOrEmpty()]
[string]
$Repository = 'PSGallery'
)
begin
{
# Set some defaults
$STP = 'Stop'
$CNT = 'Continue'
if (-not $Repository)
{
$Repository = 'PSGallery'
}
if (-not $Path)
{
$Path = 'C:\Tools\list.txt'
}
}
process
{
if ($Export)
{
Write-Verbose -Message 'Start the export job'
try
{
# Some Modules throw an error!
Write-Verbose -Message 'Get a list of modules'
$AllInstalledModule = (Get-InstalledModule -ErrorAction SilentlyContinue -WarningAction $CNT | Where-Object -FilterScript {
$_.Repository -eq $Repository
} | Select-Object -ExpandProperty name)
# Export the List to a given File
Write-Verbose -Message 'Export the Module information'
$paramSetContent = @{
Value = $AllInstalledModule
Path = $Path
Force = $true
Confirm = $false
ErrorAction = $STP
WarningAction = $CNT
}
$null = (Set-Content @paramSetContent)
}
catch
{
# get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
Write-Error -Message $info.Exception -ErrorAction $STP
return
}
}
elseif ($Import)
{
Write-Verbose -Message 'Start the import job'
try
{
Write-Verbose -Message 'Read the list of modules'
$paramGetContent = @{
Path = $Path
Force = $true
ErrorAction = $STP
WarningAction = $CNT
}
$AllInstalledModule = (Get-Content @paramGetContent)
Write-Verbose -Message 'Try to install the Modules'
foreach ($SingleInstalledModule in $AllInstalledModule)
{
Write-Verbose -Message ('Try to find {0} on {1}' -f $SingleInstalledModule, $Repository)
$FindTheModule = $null
try
{
# It a bit slower if we search for it first, but this should make the installation more robust
$paramFindModule = @{
Name = $SingleInstalledModule
Repository = $Repository
ErrorAction = $STP
WarningAction = $CNT
}
$FindTheModule = (Find-Module @paramFindModule)
if ($FindTheModule)
{
Write-Verbose -Message ('Try to install {0} from {1}' -f $SingleInstalledModule, $Repository)
try
{
$paramInstallModule = @{
Name = $SingleInstalledModule
Repository = $Repository
SkipPublisherCheck = $true
AllowClobber = $true
Force = $true
Confirm = $false
ErrorAction = $STP
WarningAction = $CNT
}
$null = (Install-Module @paramInstallModule)
}
catch
{
Write-Warning -Message ('Found {0} in {1}, but could NOT install it!' -f $SingleInstalledModule, $Repository) -ErrorAction $CNT -WarningAction $CNT
}
}
else
{
Write-Warning -Message ('Unable to find {0} in {1}?' -f $SingleInstalledModule, $Repository) -ErrorAction $CNT -WarningAction $CNT
}
}
catch
{
Write-Warning -Message ('Something went wrong with {0} in {1}?' -f $SingleInstalledModule, $Repository) -ErrorAction $CNT -WarningAction $CNT
}
}
}
catch
{
# get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
Write-Error -Message $info.Exception -ErrorAction $STP
return
}
}
else
{
Write-Error -Message 'Unknown action specified.' -Category InvalidArgument -RecommendedAction 'Check parameter' -ErrorAction $STP
return
}
}
end
{
Write-Verbose -Message 'Have a great day!'
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,59 @@
# Increases the UDP packet size to 1500 bytes for FastSend
# http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=2040065
$blnIncreaseFastSendDatagramThreshold = $true
if ($blnIncreaseFastSendDatagramThreshold)
{
#Inform user
Write-Output -InputObject 'Increasing UDP FastSend threshold'
$RegistryPath = 'HKLM:\SYSTEM\CurrentControlSet\Services\AFD\Parameters'
$RegistryName = 'FastSendDatagramThreshold'
$RegistryValue = '1500'
If (Test-Path -Path $RegistryPath)
{
$null = (New-ItemProperty -Path $RegistryPath -Name $RegistryName -Value $RegistryValue -PropertyType DWORD -Force -Confirm:$false)
Write-Output -InputObject '(CREATED)'
}
else
{
$null = (Set-ItemProperty -Path $RegistryPath -Name $RegistryName -Value $RegistryValue -Force -Confirm:$false)
Write-Output -InputObject '(MODIFIED)'
}
}
else
{
Write-Warning -Message '(skipped)'
}
# Set multiplication factor to the default UDP scavenge value (MaxEndpointCountMult)
# http://support.microsoft.com/kb/2685007/en-us
$lbnSetMaxEndpointCountMult = $true
if ($lbnSetMaxEndpointCountMult)
{
#Inform user
Write-Output -InputObject 'Set multiplication factor to the default UDP scavenge value'
$RegistryPath = 'HKLM:\SYSTEM\CurrentControlSet\Services\BFE\Parameters'
$RegistryName = 'MaxEndpointCountMult'
$RegistryValue = '0x10'
If (Test-Path -Path $RegistryPath)
{
$null = (New-ItemProperty -Path $RegistryPath -Name $RegistryName -Value $RegistryValue -PropertyType DWORD -Force -Confirm:$false)
Write-Output -InputObject '(CREATED)'
}
else
{
$null = (Set-ItemProperty -Path $RegistryPath -Name $RegistryName -Value $RegistryValue -Force -Confirm:$false)
Write-Output -InputObject '(MODIFIED)'
}
}
else
{
Write-Warning -Message '(skipped)'
}

View File

@@ -0,0 +1,247 @@
function ConvertFrom-UnixTimeStamp
{
<#
.SYNOPSIS
Converts a Timestamp (Epochdate) into Datetime
.DESCRIPTION
Converts a Timestamp (Epochdate) into Datetime
.PARAMETER TimeStamp
Timestamp (Epochdate)
.PARAMETER Milliseconds
Is the given Timestamp (Epochdate) in Miliseconds instead of Seconds?
.EXAMPLE
PS C:\> ConvertFrom-UnixTimeStamp -TimeStamp 1547839380
Converts a Timestamp (Epochdate) into Datetime
.EXAMPLE
PS C:\> ConvertFrom-UnixTimeStamp -TimeStamp 1547839380712 -Milliseconds
Converts a Timestamp (Epochdate) into Datetime, given value is in Milliseconds
.NOTES
Added the 'UniFi' (Alias for the switch 'Milliseconds') because the API returns miliseconds instead of seconds
#>
[CmdletBinding(ConfirmImpact = 'None')]
[OutputType([datetime])]
param
(
[Parameter(Mandatory,
ValueFromPipeline,
Position = 0,
HelpMessage = 'Timestamp (Epochdate)')]
[ValidateNotNullOrEmpty()]
[Alias('Epochdate')]
[long]
$TimeStamp,
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 1)]
[Alias('UniFi')]
[switch]
$Milliseconds = $false
)
begin
{
# Set some defaults
$UnixStartTime = '1/1/1970'
# Cleanup
$Result = $null
}
process
{
try
{
if ($Milliseconds)
{
$Result = ((Get-Date -Date $UnixStartTime -ErrorAction Stop -WarningAction SilentlyContinue).AddMilliseconds($TimeStamp))
}
else
{
try
{
$Result = ((Get-Date -Date $UnixStartTime -ErrorAction Stop -WarningAction SilentlyContinue).AddSeconds($TimeStamp))
}
catch
{
# Try a Fallback!
$Result = ((Get-Date -Date $UnixStartTime -ErrorAction Stop -WarningAction SilentlyContinue).AddMilliseconds($TimeStamp))
}
}
}
catch
{
# get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
$info | Out-String | Write-Verbose
Write-Error -Message ($info.Exception) -ErrorAction Stop
# Only here to catch a global ErrorAction overwrite
break
}
}
end
{
$Result
}
}
function ConvertTo-UnixTimeStamp
{
<#
.SYNOPSIS
Converts a Datetime into a Unix Timestamp (Epochdate)
.DESCRIPTION
Converts a Datetime into a Unix Timestamp (Epochdate)
.PARAMETER Date
The Date String that should be converted, default is now (if none is given)
.PARAMETER Milliseconds
Should the Timestamp (Epochdate) in Miliseconds instead of Seconds?
.EXAMPLE
PS C:\> ConvertTo-UnixTimeStamp
Converts the actual time into a Unix Timestamp (Epochdate)
.EXAMPLE
PS C:\> ConvertTo-UnixTimeStamp -Milliseconds
Converts the actual time into a Unix Timestamp (Epochdate), in milliseconds
.EXAMPLE
PS C:\> ConvertTo-UnixTimeStamp -Date ((Get-Date).AddDays(-1))
Covert the same time yesterday into a Unix Timestamp (Epochdate)
.EXAMPLE
PS C:\> ConvertTo-UnixTimeStamp -Date ((Get-Date).AddDays(-1)) -Milliseconds
Covert the same time yesterday into a Unix Timestamp (Epochdate), in milliseconds
.NOTES
Added the 'UniFi' (Alias for the switch 'Milliseconds') because the API returns milliseconds instead of seconds
#>
[CmdletBinding(ConfirmImpact = 'None')]
[OutputType([long])]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 0)]
[ValidateNotNullOrEmpty()]
[Alias('TimeStamp', 'DateTimeStamp')]
[datetime]
$Date = (Get-Date),
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 1)]
[Alias('UniFi')]
[switch]
$Milliseconds = $false
)
begin
{
# Set some defaults
$UnixStartTime = '1/1/1970'
# Cleanup
$Result = $null
}
process
{
try
{
if ($Milliseconds)
{
$Result = ([long]((New-TimeSpan -Start (Get-Date -Date $UnixStartTime -ErrorAction Stop -WarningAction SilentlyContinue) -End (Get-Date -Date $Date -ErrorAction Stop -WarningAction SilentlyContinue) -ErrorAction Stop -WarningAction SilentlyContinue).TotalMilliseconds))
}
else
{
$Result = ([long]((New-TimeSpan -Start (Get-Date -Date $UnixStartTime -ErrorAction Stop -WarningAction SilentlyContinue) -End (Get-Date -Date $Date -ErrorAction Stop -WarningAction SilentlyContinue) -ErrorAction Stop -WarningAction SilentlyContinue).TotalSeconds))
}
}
catch
{
# get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
$info | Out-String | Write-Verbose
Write-Error -Message ($info.Exception) -ErrorAction Stop
# Only here to catch a global ErrorAction overwrite
break
}
}
end
{
$Result
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,156 @@
#requires -Version 3.0 -Modules PowerShellGet
function Update-ModuleFromPSGallery
{
<#
.SYNOPSIS
Update a given PowerShell Module with the latest version from the Gallery
.DESCRIPTION
Update a given PowerShell Module with the latest version from the Gallery, if needed
.PARAMETER ModuleName
Name of the PowerShell Module
.EXAMPLE
PS C:\> Update-ModuleFromPSGallery -ModuleName 'PowerShellGet'
Check if an update for 'PowerShellGet' is needed, if a newer version is available it will install it
.EXAMPLE
PS C:\> 'PowerShellGet' | Update-ModuleFromPSGallery
Check if an update for 'PowerShellGet' is needed, if a newer version is available it will install it
.EXAMPLE
PS C:\> Get-InstalledModule -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Update-ModuleFromPSGallery -ErrorAction Continue -WarningAction SilentlyContinue
Check if an update for for any Gallery Module is needed, if a newer version is available it will install it
.NOTES
Just a quick an dirty function to keep a given Module up-to-date
If you want to update any system-wide installed module, you need to start this elevated (Run as admin)
#>
[CmdletBinding(ConfirmImpact = 'Low')]
param
(
[Parameter(Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position = 0,
HelpMessage = 'Name of the PowerShell Module')]
[ValidateNotNullOrEmpty()]
[Alias('Module', 'Name')]
[string[]]
$ModuleName
)
begin
{
$InstalledModuleInfo = $null
$InstalledVersion = $null
$OnlineVersion = $null
$ModuleScope = $null
}
process
{
foreach ($SingleModuleName in $ModuleName)
{
if (Get-InstalledModule -Name $SingleModuleName -ErrorAction SilentlyContinue -WarningAction SilentlyContinue)
{
# unload the module
$null = (Remove-Module -Name $SingleModuleName -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue)
# Get the Info about the module (local)
$InstalledModuleInfo = (Get-Module -Name $SingleModuleName -ListAvailable -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Select-Object -Property Version, ModuleBase)
# Save the Version Info
[Version]$InstalledVersion = (($InstalledModuleInfo).Version)
# Get the Info about the module from the Gallery
[Version]$OnlineVersion = (Find-Module -Name $SingleModuleName -Repository PSGallery -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Select-Object -ExpandProperty Version)
if ($InstalledVersion -lt $OnlineVersion)
{
if ((($InstalledModuleInfo).ModuleBase) -like ((($InstalledModuleInfo).ModuleBase) + '*'))
{
$ModuleScope = 'AllUsers'
}
else
{
$ModuleScope = 'CurrentUser'
}
try
{
Write-Verbose -Message ('[TRY] Update: {0}' -f $SingleModuleName)
$null = (Update-Module -Name $SingleModuleName -Scope $ModuleScope -ErrorAction Stop -WarningAction Continue -Force)
Write-Verbose -Message ('[SUCCESS] Update: {0}' -f $SingleModuleName)
}
catch
{
# Get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
Write-Warning -Message ('[FAILED] Update: {0}' -f $SingleModuleName)
}
}
}
}
}
end
{
$InstalledModuleInfo = $null
$InstalledVersion = $null
$OnlineVersion = $null
$ModuleScope = $null
}
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,139 @@
#requires -Version 3.0 -Modules CimCmdlets
<#
.SYNOPSIS
Simple script to generate a lot of CPU load
.DESCRIPTION
Generate a lot of CPU load based on the number logical processors
.PARAMETER Overload
Double the number of jobs.
Normally the script will start one job per logical Processors,
this switch will double the number. This will overload the server.
Hint: If your server supports Hyper-threading,
the number of logical Processors is the doubled amount of cores!
WARNING: The system might become unstable!
.EXAMPLE
PS C:\> .\invoke-CPUWorkload.ps1
.NOTES
Nothing fancy, just a plain and easy script to generate a lot of load.
Created to do a stress test on new servers.
#>
[CmdletBinding(ConfirmImpact = 'Medium')]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[Alias('Double')]
[switch]
$Overload
)
#region ClearRunningCPUWorkloadJobs
function Clear-RunningCPUWorkloadJobs
{
<#
.SYNOPSIS
Get, stop, and remove all running CPUWorkloadJobs
.DESCRIPTION
Get, stop, and remove all running CPUWorkloadJobs
.EXAMPLE
PS C:\> Clear-RunningCPUWorkloadJobs
.NOTES
Internal Helper for the "Generate a log of CPU load" script
#>
[CmdletBinding(ConfirmImpact = 'Low')]
param ()
# Get a list of running jobs
$CPUWorkloadJobList = (Get-Job -Name 'CPUWorkload_*' -ErrorAction SilentlyContinue)
# Cleanup
if ($CPUWorkloadJobList)
{
$null = ($CPUWorkloadJobList | Stop-Job -ErrorAction SilentlyContinue)
$null = ($CPUWorkloadJobList | Receive-Job -AutoRemoveJob -Wait -ErrorAction SilentlyContinue)
}
}
#endregion ClearRunningCPUWorkloadJobs
# Get the number of logical processors
[int]$NumThreads = (Get-CimInstance -ClassName Win32_Processor | Select-Object -ExpandProperty NumberOfLogicalProcessors)
if (($PSCmdlet.MyInvocation.BoundParameters['Overload']).IsPresent)
{
$NumThreads = ($NumThreads * 2)
Write-Warning -Message 'You decide to overload the system! This may cause the system to become unstable.'
}
# Stop and cleanup, if needed
$null = (Clear-RunningCPUWorkloadJobs)
# Start to generate load, based on the system capabilities
foreach ($loop in 1 .. $NumThreads)
{
$null = (Start-Job -Name ('CPUWorkload_' + $loop) -ScriptBlock {
[float]$result = 1
while ($true)
{
[float]$x = Get-Random -Minimum 1 -Maximum 999999999
$result = $result * $x
}
})
}
<#
We start the work with Start-Job (in the background)
If this can cause an overload, the system might become unstable and it might take very long to respond.
CTRL+C will not end background execution of worker threads, it will just kill this script
#>
Read-Host -Prompt 'Press any key to exit the test.'
# Stop and cleanup, if needed
$null = (Clear-RunningCPUWorkloadJobs)
# Ensure all jobs are gone
$null = (Clear-RunningCPUWorkloadJobs)
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,198 @@
#requires -Modules PowerShellGet -Version 2.0 -RunAsAdministrator
<#
.SYNOPSIS
Install some DSC Resources
.DESCRIPTION
Getting, install, or update DSC Resources I want to have.
It could be used to install every Module from the Gallery.
However, this is something I do with DSC afterwards!
.EXAMPLE
PS C:\> .\invoke-GetDSCResources.ps1
.EXAMPLE
PS C:\> .\invoke-GetDSCResources.ps1 -verbose
VERBOSE: Populating RepositorySourceLocation property for module PSDscResources.
VERBOSE: Try to update PSDscResources
VERBOSE: Updated PSDscResources
.NOTES
Small script I created for myself.
I have to prepare DSC systems from time to time, and I want to have the same set of DSC resources on all of them.
Mainly because I'm lazy, but I'm an old-school Unix guy: Never type something more than two times: AUTOMATE.
I install the resources system wide!
That is why we have the Elevated Shell requirement (#Requires -RunAsAdministrator).
If you want to use it just for the current user, change the Scope in $paramInstallModule from 'AllUsers' to 'CurrentUser'.
TODO: Pester Test is missing
DONE: Make it more robust
Disclaimer: The code is provided 'as is,' with all possible faults, defects or errors, and without warranty of any kind.
Author: Joerg Hochwald
.LINK
Author http://jhochwald.com
#>
[CmdletBinding()]
param ()
begin
{
# Define some defaults
$STP = 'Stop'
$SC = 'SilentlyContinue'
# Suppressing the PowerShell Progress Bar
$script:ProgressPreference = $SC
# Create a list of the DSC Resources I want
$NewDSCModules = @(
'PSDscResources',
'xNetworking',
'xPSDesiredStateConfiguration',
'xWebAdministration',
'xCertificate',
'xComputerManagement',
'xActiveDirectory',
'SystemLocaleDsc',
'xRemoteDesktopAdmin',
'xPendingReboot',
'xSmbShare',
'xWindowsUpdate',
'xDscDiagnostics',
'xCredSSP',
'xDnsServer',
'xWinEventLog',
'xDhcpServer',
'xHyper-V',
'xStorage',
'xWebDeploy'
'xRemoteDesktopSessionHost',
'xDismFeature',
'xSystemSecurity',
'WebAdministrationDsc',
'OfficeOnlineServerDsc',
'AuditPolicyDsc',
'xDFS',
'SecurityPolicyDsc',
'xReleaseManagement',
'xExchange',
'xDefender',
'xWindowsEventForwarding',
'cHyper-V'
)
}
process
{
foreach ($NewDSCModule in $NewDSCModules)
{
# Cleanup
$ModuleIsAvailable = $null
# Check: Do I have the resource?
$paramGetModule = @{
ListAvailable = $true
Name = $NewDSCModule
ErrorAction = $SC
WarningAction = $SC
}
$ModuleIsAvailable = (Get-Module @paramGetModule)
if (-not ($ModuleIsAvailable))
{
# Nope: Install the resource
try
{
Write-Verbose -Message ('Try to install {0}' -f $NewDSCModule)
$paramInstallModule = @{
Name = $NewDSCModule
Scope = AllUsers
Force = $true
ErrorAction = $STP
WarningAction = $SC
}
$null = (Install-Module @paramInstallModule)
Write-Verbose -Message ('Installed {0}' -f $NewDSCModule)
}
catch
{
# Whoopsie
$paramWriteWarning = @{
Message = ('Sorry, unable to install {0}' -f $NewDSCModule)
ErrorAction = $SC
}
Write-Warning @paramWriteWarning
}
}
else
{
try
{
Write-Verbose -Message ('Try to update {0}' -f $NewDSCModule)
# TODO: Implement the check from invoke-ModuleUpdates.ps1 to prevent the unneeded update tries.
$paramUpdateModule = @{
Name = $NewDSCModule
Confirm = $false
ErrorAction = $STP
WarningAction = $SC
}
$null = (Update-Module @paramUpdateModule)
Write-Verbose -Message ('Updated {0}' -f $NewDSCModule)
}
catch
{
# Whoopsie
$paramWriteWarning = @{
Message = ('Sorry, unable to update {0}' -f $NewDSCModule)
ErrorAction = $SC
}
Write-Warning @paramWriteWarning
}
}
}
}
end
{
# No longer suppressing the PowerShell Progress Bar
$script:ProgressPreference = 'Continue'
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER

View File

@@ -0,0 +1,120 @@
#Requires -Version 3.0 -Modules PowerShellGet -RunAsAdministrator
<#
.SYNOPSIS
PowerShell Module maintenance
.DESCRIPTION
Quick and dirty script that removes all older versions of all installed PowerShell Modules.
.EXAMPLE
PS C:\> .\invoke-ModuleMaint.ps1
# Removes all old versions for all installed PowerShell Modules.
.NOTES
Why:
I do an automated update of my Modules, this process just updates straight to the latest and
greatest version of each installed module. I ended up with a bunch of older version for most
Modules, and I needed something to clean this up.
I found several stuff that does the same thing, but they all use "Get-InstalledModule" and the
performance of this command is terrible! I have to use "Uninstall-Module" that is slow enough,
so I needed something that runs faster on my system, where I have a lot of Modules installed.
Please note:
This will try to remove all older versions of all installed powerShell versions.
There might be issues with newer versions, so be aware of that.
There is no check, just a simple removal off all older versions.
#>
[CmdletBinding()]
param ()
begin
{
# Get all Modules with every Version that the system knows about.
$AllModules = (Get-Module -ListAvailable -Refresh)
}
process
{
# Now we initiate a loop over the information we have.
foreach ($SingleModule in $AllModules)
{
# Get the detailed information for the Module
$paramGetModule = @{
ListAvailable = $true
Name = $SingleModule.name
}
$SingleInstance = (Get-Module @paramGetModule)
# Do we have more than one installed version?
if ($SingleInstance -is [array])
{
# What is the latest and greatest?
$latest = (($SingleInstance | Sort-Object -Property Version -Descending)[0]).Version
# Now loop over all older versions
foreach ($VersionToRemove in $SingleInstance)
{
if (($VersionToRemove.Version -lt $latest))
{
try
{
# This is damn slow, but it is the safest way to do it!
$paramUninstallModule = @{
Name = $VersionToRemove.Name
RequiredVersion = $VersionToRemove.Version
Force = $true
ErrorAction = 'Stop'
WarningAction = 'SilentlyContinue'
Confirm = $false
}
$null = (Uninstall-Module @paramUninstallModule)
}
catch
{
# TODO: Check if we need something here. Or do we just want to catch it?
Write-Verbose -Message 'Whoops'
}
}
}
}
}
}
end
{
# TODO: Check if we need something here.
Write-Verbose -Message 'We are done, have a nice day!'
}
#region LICENSE
<#
BSD 3-Clause License
Copyright (c) 2021, enabling Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
#endregion LICENSE
#region DISCLAIMER
<#
DISCLAIMER:
- Use at your own risk, etc.
- This is open-source software, if you find an issue try to fix it yourself. There is no support and/or warranty in any kind
- This is a third-party Software
- The developer of this Software is NOT sponsored by or affiliated with Microsoft Corp (MSFT) or any of its subsidiaries in any way
- The Software is not supported by Microsoft Corp (MSFT)
- By using the Software, you agree to the License, Terms, and any Conditions declared and described above
- If you disagree with any of the terms, and any conditions declared: Just delete it and build your own solution
#>
#endregion DISCLAIMER