├── .gitignore
├── Network
└── disable-NetBios.ps1
├── ActiveDirectory
├── Configure-AD.ps1
├── get-CVE20201472Events.ps1
├── Get-LAPSAuditReport.ps1
├── install-AD.ps1
├── install-DC.ps1
├── move-FSMO.ps1
├── execute-RemoteScriptWithLAPS.ps1
├── Get-ADPermissionsReport.ps1
├── Reset-DSRM.ps1
├── Locate-46xx.ps1
├── Locate-ADLockout.ps1
├── get-adinfo.ps1
└── Repair-DFSR.ps1
├── Dokumente
└── Zertifizierungsstellen mit Windows Server 2012R2.pdf
├── Linux-Files
├── allow_github.squid
├── allow_vscode.squid
├── allow_psgallery.squid
└── allow_windowsupdate.squid
├── .github
├── workflows
│ └── gernerate-docs.yml
├── FUNDING.yml
└── copilot-instructions.md
├── Intune
├── Readme.md
├── create-package.ps1
└── get-AutopilotLogs.ps1
├── BitLocker
├── Start-Bitlocker.ps1
├── List-BitLockerrecoveryKeys.ps1
└── Update-BitLockerRecovery.ps1
├── Azure
├── Install-AzModule.ps1
└── Install-AzCopy.ps1
├── WSUS
├── Reset-WSUSClient.cmd
└── start-WsusServerSync.ps1
├── GPO
├── get-GPOreport.ps1
├── invoke-GPupdateDomain.ps1
├── Check-LocalGroupPolicy.ps1
└── get-GPOBackup.ps1
├── install-greenshot.ps1
├── generate-hosts.ps1
├── User
├── Get-LastLogonOU.ps1
└── create-user.ps1
├── Windows
├── set-cert4rdp.ps1
└── Remove-AzureArc.ps1
├── README.md
├── Set-Network.ps1
├── send-files.ps1
├── Exchange
├── Set-Ex2013Vdir.ps1
└── Set-MaintananceMode.ps1
├── Get-WindowsSid.ps1
├── Set-WinRelease.ps1
└── New-DokuwikiAnimal.ps1
/.gitignore:
--------------------------------------------------------------------------------
1 | hosts
2 |
--------------------------------------------------------------------------------
/Network/disable-NetBios.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/InfrastructureHeroes/Scipts/HEAD/Network/disable-NetBios.ps1
--------------------------------------------------------------------------------
/ActiveDirectory/Configure-AD.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/InfrastructureHeroes/Scipts/HEAD/ActiveDirectory/Configure-AD.ps1
--------------------------------------------------------------------------------
/Dokumente/Zertifizierungsstellen mit Windows Server 2012R2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/InfrastructureHeroes/Scipts/HEAD/Dokumente/Zertifizierungsstellen mit Windows Server 2012R2.pdf
--------------------------------------------------------------------------------
/Linux-Files/allow_github.squid:
--------------------------------------------------------------------------------
1 | # GitHub URL list for squid ACL (Fabian Niesen - InfrastrukturHelden.de)
2 | # add to squid.conf:
3 | # acl github dstdomain "/etc/squid/allow_github.squid"
4 | # http_access allow github
5 |
6 | .github.com
7 |
--------------------------------------------------------------------------------
/.github/workflows/gernerate-docs.yml:
--------------------------------------------------------------------------------
1 | name: generate docs
2 | on:
3 | [push]
4 | jobs:
5 | docs:
6 | runs-on: ubuntu-latest
7 | steps:
8 | - name: Checkout
9 | uses: actions/checkout@main
10 | - name: Generate docs
11 | uses: Microsoft/ps-docs@main
12 |
--------------------------------------------------------------------------------
/Linux-Files/allow_vscode.squid:
--------------------------------------------------------------------------------
1 | # Visual Studio Code URL list for squid ACL (Fabian Niesen - InfrastrukturHelden.de)
2 | # add to squid.conf:
3 | # acl vscode dstdomain "/etc/squid/allow_vscode.squid"
4 | # http_access allow vscode
5 |
6 | # extension gallery
7 | marketplace.visualstudio.com
8 | .vsassets.io
9 |
10 |
--------------------------------------------------------------------------------
/Intune/Readme.md:
--------------------------------------------------------------------------------
1 | # Microsoft Intune Scripts
2 |
3 | ## get-AutopilotLogs.ps1
4 | Script to gather some Logs and Information for troubleshoot failed Autopilot Pre-Provisionings. Best to be run fro USB thumbdrive.
5 |
6 | ## create-package.ps1
7 | Create Intunewin Files from Sourcefolders. Install Commands must be located in install.cmd
8 |
9 | Check https://github.com/InfrastructureHeroes/Intune-Apps for a more complete solution
10 |
--------------------------------------------------------------------------------
/Linux-Files/allow_psgallery.squid:
--------------------------------------------------------------------------------
1 | # NuGet URL list for squid ACL (Fabian Niesen - InfrastrukturHelden.de)
2 | # based upon https://learn.microsoft.com/en-us/powershell/gallery/getting-started?view=powershellget-2.x
3 | # add to squid.conf:
4 | # acl psgallery dstdomain "/etc/squid/allow_psgallery.squid"
5 | # http_access allow psgallery
6 |
7 | go.microsoft.com
8 | onegetcdn.azureedge.net
9 | psg-prod-centralus.azureedge.net
10 | psg-prod-eastus.azureedge.net
11 | az818661.vo.msecnd.net
12 | # For Website
13 | devopsgallerystorage.blob.core.windows.net
14 | *.powershellgallery.com
15 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: InfrastructureHeroes
4 | patreon: infrastrukturhelden
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: fabian_niesen
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/BitLocker/Start-Bitlocker.ps1:
--------------------------------------------------------------------------------
1 | $Pin = ConvertTo-SecureString "123456" -AsPlainText -Force
2 | Add-BitlockerKeyProtector -MountPoint $env:SystemDrive -RecoveryPasswordProtector
3 | $BLV = Get-BitLockerVolume -MountPoint "C:"
Backup-BitLockerKeyProtector -MountPoint "C:" -KeyProtectorId $BLV.KeyProtector[0].KeyProtectorId
4 | Enable-BitLocker -MountPoint C: -TpmAndPinProtector -Pin $Pin -SkipHardwareTest -UsedSpaceOnly
5 | While ((Get-BitLockerVolume -MountPoint $env:SystemDrive).VolumeStatus -eq "EncryptionInProgress") {
6 | $encPercent = (Get-BitLockerVolume -MountPoint $env:SystemDrive).EncryptionPercentage
7 | Write-Progress -Activity "Encrypting $env:SystemDrive" -PercentComplete $encPercent -Status "$encPercent% complete"
8 | sleep -m 1000
9 | }
10 | Write-Progress -Activity "Encrypting $env:SystemDrive" -Status "Done" -Completed
11 |
--------------------------------------------------------------------------------
/Linux-Files/allow_windowsupdate.squid:
--------------------------------------------------------------------------------
1 | # Windows Update URL list for squid ACL (Fabian Niesen - InfrastrukturHelden.de)
2 | # based upon https://learn.microsoft.com/de-de/security-updates/WindowsUpdateServices/18127640 and https://learn.microsoft.com/en-us/windows-server/administration/windows-server-update-services/deploy/2-configure-wsus#211-connection-from-the-wsus-server-to-the-internet
3 | # add to squid.conf:
4 | # acl windowsupdate dstdomain "/etc/squid/allow_windowsupdate.squid"
5 | # http_access allow windowsupdate
6 |
7 |
8 | definitionupdates.microsoft.com
9 | .windowsupdate.microsoft.com
10 | .update.microsoft.com
11 | .windowsupdate.com
12 | download.microsoft.com
13 | wustat.windows.com
14 | ntservicepack.microsoft.com
15 | go.microsoft.com
16 | .delivery.mp.microsoft.com
17 | download.visualstudio.microsoft.com
18 | www.microsoft.com
19 |
20 |
--------------------------------------------------------------------------------
/BitLocker/List-BitLockerrecoveryKeys.ps1:
--------------------------------------------------------------------------------
1 | $computers = get-adobject -Filter * | Where-Object {$_.ObjectClass -eq "msFVE-RecoveryInformation"}
2 |
3 | $key = (read-host -Prompt "Enter starting portion of recovery key ID").ToUpper()
4 | $records = $computers | where {$_.DistinguishedName -like "*{$key*"}
5 | foreach ($rec in $records) {
6 | $computer = get-adcomputer -identity ($records.DistinguishedName.Split(",")[1]).split("=")[1]
7 | $recoveryPass = Get-ADObject -Filter {objectclass -eq 'msFVE-RecoveryInformation'} -SearchBase $computer.DistinguishedName -Properties 'msFVE-RecoveryPassword' | where {$_.DistinguishedName -like "*$key*"}
8 | [pscustomobject][ordered]@{
9 | Computer = $computer
10 | 'Recovery Key ID' = $rec.Name.Split("{")[1].split("}")[0]
11 | 'Recovery Password' = $recoveryPass.'msFVE-RecoveryPassword'
12 | } | Format-List
13 | }
--------------------------------------------------------------------------------
/Azure/Install-AzModule.ps1:
--------------------------------------------------------------------------------
1 | Write-Verbose "Check for Admin"
2 | If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
3 | {
4 | $arguments = "& '" + $myinvocation.mycommand.definition + "'"
5 | Start-Process powershell -Verb runAs -ArgumentList $arguments
6 | Break
7 | }
8 | If (!(Get-PackageProvider NuGet -ErrorAction SilentlyContinue).count -ge 1 ) { Install-PackageProvider -Name NuGet -Force -Confirm:$false } ELSE { Write-Output "NuGet Provider already configured"}
9 | If (!(get-module PowerShellGet -ErrorAction SilentlyContinue).count -ge 1 ) { Install-Module PowerShellGet -Force -Confirm:$false } ELSE { Write-Output "PowershellGet already installed"}
10 | If (!(get-command Connect-AzAccount -ErrorAction SilentlyContinue).count -ge 1 ) { Install-Module Az -Force -Confirm:$false } ELSE { Write-Output "Az Module already installed"}
--------------------------------------------------------------------------------
/ActiveDirectory/get-CVE20201472Events.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Checks all Domain Controller for Event ID 5827-5829 in the System Eventlog
4 |
5 | .DESCRIPTION
6 | Checks all Domain Controller for Event ID 5827-5829 in the System Eventlog. This are the Event for connections witch will be blockt startin 9 Feb. 2021 due CVE-2020-1472.
7 |
8 | .EXAMPLE
9 | C:\PS> get-CVE20201472Events.ps1
10 |
11 | .NOTES
12 | Author : Fabian Niesen (www.fabian-niesen.de)
13 | Filename : get-CVE20201472Events.ps1
14 | Requires : PowerShell Version 3.0
15 | Version : 1.0
16 | History : 1.0 FN 17.01.2021 initial version
17 |
18 |
19 | .LINK
20 | https://www.infrastrukturhelden.de/?p=14850
21 | #>
22 |
23 | Param()
24 |
25 | $ErrorActionPreference = "Stop"
26 |
27 | try { Import-Module activedirectory } catch { Write-Warning "ActiveDirectory Module ist missing. Please install first"; break }
28 | $DCs = Get-ADDomainController -Filter { OperatingSystemVersion -like "*" }
29 | Write-Output "Found $($DCs.count) Domain Controllers in Active Directory"
30 | Write-Progress -activity "Query Eventlogs" -Status "starting" -PercentComplete "0" -Id 1
31 | [int]$i = "0"
32 | ForEach ($DC in $DCs)
33 | {
34 | $i++
35 | Write-Progress -activity "Query Eventlogs" -Status "$($DC.HostName)" -PercentComplete ((($i / $DCs.count)*100)-5) -Id 1
36 | Write-Output $DC.HostName
37 | Get-EventLog -ComputerName $DC.HostName -LogName "System" | Where-Object { $_.EventID -eq 5829 -or $_.EventID -eq 5827 -or $_.EventID -eq 5828 } | select -First 10
38 | }
--------------------------------------------------------------------------------
/ActiveDirectory/Get-LAPSAuditReport.ps1:
--------------------------------------------------------------------------------
1 | #@{Name="Title";Expression={[string]$_.Title}},@{Name="KB Article";Expression={[string]::join(' | ',$_.KnowledgebaseArticles[0])}},
2 |
3 | $Events = (Get-WinEvent -FilterHashtable @{ LogName='Security'; Id='4662'; StartTime=$((Get-Date).AddHours(-1)) } | Where-Object { $_.Message -like "*f3531ec6-6330-4f8e-8d39-7a671fbac605*" } )
4 |
5 | $Results = @()
6 | ForEach ($Event in $Events) {
7 | [XML]$XMLEvent = $Event.ToXml()
8 | # $Event.TimeCreated
9 | # $(($XMLEvent.Event.EventData.Data | ? { $_.Name -like "SubjectUserName"}).'#text')
10 | $(($XMLEvent.Event.EventData.Data | ? { $_.Name -like "SubjectUserName"}).'#text')
11 | $Results += [PSCustomObject]@{
12 | 'TimeCreated' = $Event.TimeCreated
13 | 'SubjectUserName' = $(($XMLEvent.Event.EventData.Data | ? { $_.Name -like "SubjectUserName"}).'#text')
14 | 'MachineName' = $Event.MachineName
15 | 'KeywordsDisplayNames' = $Event.KeywordsDisplayNames
16 | 'Computer' = $XMLEvent.Event.System.Computer
17 | }
18 | }
19 | $Results | ft -AutoSize
20 |
21 | <# .Event.EventData.data
22 |
23 | Name #text
24 | ---- -----
25 | SubjectUserSid S-1-5-18
26 | SubjectUserName DC01$
27 | SubjectDomainName lapsifh
28 | SubjectLogonId 0x1e78212
29 | ObjectServer DS
30 | ObjectType %{bf967a86-0de6-11d0-a285-00aa003049e2}
31 | ObjectName %{c9064d61-1d2b-46f0-b9ca-b4d5b35249c7}
32 | OperationType Object Access
33 | HandleId 0x0
34 | AccessList %%7688...
35 | AccessMask 0x100
36 | Properties %%7688...
37 | AdditionalInfo -
38 | AdditionalInfo2
39 | #>
--------------------------------------------------------------------------------
/Azure/Install-AzCopy.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Download and install the actual version of AzCopy for the executing User
4 |
5 | .DESCRIPTION
6 | Download and install the actual version of AzCopy for the executing User
7 |
8 | .EXAMPLE
9 | C:\PS> Install-AzCopy.ps1
10 |
11 | .EXAMPLE
12 | C:\PS> Install-AzCopy.ps1 -targetfolder'C:\Program Files'
13 |
14 |
15 | .PARAMETER targetfolder
16 | Path to install AzCopy. Default is UserProfile
17 |
18 | .NOTES
19 | Author : Fabian Niesen (www.fabian-niesen.de)
20 | Filename : Install-AzCopy.ps1
21 | Requires : PowerShell Version 3.0
22 | Version : 1.0
23 | History : 1.0 FN 05.08.2022 initial version
24 |
25 | .LINK
26 | https://github.com/InfrastructureHeroes/Scipts
27 | #>
28 |
29 | Param(
30 | [Parameter(Mandatory=$false, Position=0, ValueFromPipeline=$true)]
31 | [String]$targetfolder = $env:USERPROFILE
32 | )
33 |
34 | #Internal parameters
35 | $zipfile = $targetfolder + "\AzCopy.zip"
36 | $azfolder = $targetfolder + "\AzCopy"
37 | #Download AzCopy to Profile
38 | Invoke-WebRequest -Uri "https://aka.ms/downloadazcopy-v10-windows" -OutFile $zipfile -UseBasicParsing
39 |
40 | #Expand Archive and remove ZIP
41 | Expand-Archive $zipfile $azfolder -Force
42 | Remove-Item $zipfile -Force
43 | #Move exe from Subfolder, but leave subfolder for Version lookup
44 | Get-ChildItem $($azfolder +"\*\azcopy.exe") | Move-Item -Destination $azfolder -Force
45 | #Set Path for the user
46 | $userenvpath = [System.Environment]::GetEnvironmentVariable("Path", "User")
47 | IF ($userenvpath.contains($azfolder)) { Write-Output "Path already set" } Else { [System.Environment]::SetEnvironmentVariable("PATH", $userenv + ";"+$azfolder , "User") }
--------------------------------------------------------------------------------
/Intune/create-package.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Create Intunewin Files from Sourcefolders
4 |
5 | .DESCRIPTION
6 | Create Intunewin Files from Sourcefolders. Install Commands must be located in install.cmd
7 |
8 | .EXAMPLE
9 | create-package.ps1 -workpath "path to Install" -ContentPrepTool "Path to ContentPrepTool Executable file"
10 |
11 | .PARAMETER workpath
12 | Workfolder for Win32 app packaging. Source files must be in subfolder "Source\Application Name". Output will be in "Output"
13 |
14 | .PARAMETER ContentPrepTool
15 | Path to ContentPrepTool Executable file
16 |
17 | .NOTES
18 | Author : Fabian Niesen
19 | Filename : create-package.ps1
20 | Requires : PowerShell Version 3.0
21 | Version : 1.0
22 | History : 1.0.0 FN 19.04.2021 initial version
23 |
24 | .LINK
25 | https://github.com/FabianNiesen/Infrastrukturhelden.de
26 | #>
27 |
28 | Param(
29 | [Parameter(Mandatory=$false, Position=0, ValueFromPipeline=$False)]
30 | [String]$workpath = "C:\Users\fabian_niesen\OneDrive - Dell Technologies\Documents\_Install",
31 | [Parameter(Mandatory=$false, Position=0, ValueFromPipeline=$False)]
32 | [String]$ContentPrepTool ="C:\Users\fabian_niesen\OneDrive - Dell Technologies\Documents\GitHub\Microsoft-Win32-Content-Prep-Tool\IntuneWinAppUtil.exe"
33 | )
34 | $date = get-date -format yyyyMMdd-HHmm
35 | Write-Progress -activity "Preparing Workdir: $workdir" -Status "starting" -PercentComplete "0" -Id 1
36 | [int]$i = "0"
37 | $Sources = (Get-ChildItem -Path $($workpath+"\Source")).Name
38 | foreach ($Source in $Sources)
39 | {
40 | $i++
41 | Write-Progress -activity "Processing Sources" -Status "$($Source)" -PercentComplete (($i / $Sources.count)*100) -Id 1
42 | Write-Verbose $Source
43 | $c = $workpath+"\Source\"+$Source
44 | $s = $workpath+"\Source\"+$Source+"\install.cmd"
45 | $o = $workpath+"\Output\"+$date+"\"+$Source
46 | Write-Verbose "Starte ContentPrep"
47 | & $ContentPrepTool -c $c -s $s -o $o -q
48 | Write-Verbose "ContentPrep abgeschlossen"
49 | }
50 |
--------------------------------------------------------------------------------
/ActiveDirectory/install-AD.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 |
4 | .DESCRIPTION
5 |
6 | .EXAMPLE
7 |
8 | .INPUTS
9 | Keine.
10 | .OUTPUTS
11 | Keine.
12 | .NOTES
13 | Author : Fabian Niesen
14 | Filename :
15 | Requires : PowerShell Version 2.0
16 |
17 | Version : 0.1
18 | History : 0.1 FN 26.111.2015 initial version
19 |
20 | .LINK
21 |
22 | #>
23 | # Variable declaration
24 | $DOM =""
25 | $NETBIOS =""
26 | $SMADMIPW =""
27 |
28 | # End of declaration - do not edit below this Point!
29 |
30 | $ErrorActionPreference = "Stop"
31 | $before = Get-Date
32 | $date = get-date -format yyyyMMdd-HHmm
33 | $ErrorLog =$BackupPath+$date+"-error.log"
34 | $WarningLog =$BackupPath+$date+"-warning.log"
35 |
36 | If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole( [Security.Principal.WindowsBuiltInRole] "Administrator"))
37 | {
38 | Write-Warning "You need Admin Permissions to run this script!"| Out-file $ErrorLog -Append
39 | break
40 | }
41 |
42 | Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools
Import-Module ADDSDeployment
Install-ADDSForest `
43 | -CreateDnsDelegation:$false `
44 | -DatabasePath "C:\Windows\NTDS" `
45 | -DomainMode "Win2012R2" `
46 | -DomainName $DOM `
47 | -DomainNetbiosName $NETBIOS `
48 | -ForestMode "Win2012R2" `
49 | -InstallDns:$true `
50 | -LogPath "C:\Windows\NTDS" `
51 | -NoRebootOnCompletion:$false `
52 | -SysvolPath "C:\Windows\SYSVOL" `
53 | -Force:$true `
54 | -SafeModeAdministratorPassword (ConvertTo-SecureString $SMADMIPW -AsPlainText -Force)
55 |
56 |
57 |
58 |
59 | $after = Get-Date
60 |
61 | $time = $after - $before
62 | $buildTime = "`nBuild finished in ";
63 | if ($time.Minutes -gt 0)
64 | {
65 | $buildTime += "{0} minute(s) " -f $time.Minutes;
66 | }
67 |
68 | $buildTime += "{0} second(s)" -f $time.Seconds;
69 | Write-host "$buildTime"
--------------------------------------------------------------------------------
/ActiveDirectory/install-DC.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 |
4 | .DESCRIPTION
5 |
6 | .EXAMPLE
7 |
8 | .INPUTS
9 | Keine.
10 | .OUTPUTS
11 | Keine.
12 | .NOTES
13 | Author : Fabian Niesen
14 | Filename :
15 | Requires : PowerShell Version 2.0
16 |
17 | Version : 0.1
18 | History : 0.1 FN 26.111.2015 initial version
19 |
20 | .LINK
21 |
22 | #>
23 |
24 | Param(
25 | [Parameter(Mandatory=$false, ValueFromPipeline=$True)]
26 | [String]$DOM ="demo.infrastrukturhelden.de",
27 | [Parameter(Mandatory=$false, ValueFromPipeline=$True)]
28 | [String]$NETBIOS ="DEMO",
29 | [Parameter(Mandatory=$false, ValueFromPipeline=$True)]
30 | [String]$SMADMINPW ="Chang3M3!"
31 | )
32 |
33 |
34 | # End of declaration - do not edit below this Point!
35 |
36 | $ErrorActionPreference = "Stop"
37 | $before = Get-Date
38 | $date = get-date -format yyyyMMdd-HHmm
39 | $ErrorLog =$BackupPath+$date+"-error.log"
40 | $WarningLog =$BackupPath+$date+"-warning.log"
41 |
42 | If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole( [Security.Principal.WindowsBuiltInRole] "Administrator"))
43 | {
44 | Write-Warning "You need Admin Permissions to run this script!"| Out-file $ErrorLog -Append
45 | break
46 | }
47 |
48 | Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools
49 | Import-Module ADDSDeployment
50 | Install-ADDSForest -CreateDnsDelegation:$false -DatabasePath "C:\Windows\NTDS" -DomainMode "Win2012R2" -DomainName $DOM -DomainNetbiosName $NETBIOS -ForestMode "Win2012R2" -InstallDns:$true -LogPath "C:\Windows\NTDS" -NoRebootOnCompletion:$false -SysvolPath "C:\Windows\SYSVOL" -Force:$true -SafeModeAdministratorPassword (ConvertTo-SecureString $SMADMINPW -AsPlainText -Force)
51 |
52 | $after = Get-Date
53 |
54 | $time = $after - $before
55 | $buildTime = "`nBuild finished in ";
56 | if ($time.Minutes -gt 0)
57 | {
58 | $buildTime += "{0} minute(s) " -f $time.Minutes;
59 | }
60 |
61 | $buildTime += "{0} second(s)" -f $time.Seconds;
62 | Write-host "$buildTime"
--------------------------------------------------------------------------------
/WSUS/Reset-WSUSClient.cmd:
--------------------------------------------------------------------------------
1 | @Echo off
2 | Echo ===WSUS Client reset by Fabian Niesen - www.infratrukturhelden.de ===
3 | Echo Stopping BITS
4 | net stop bits
5 | ECHO =Stopping Windows Update Service=
6 | net stop wuauserv
7 | timeout /t 30 /nobreak
8 | Echo =de-register wuaueng.dll=
9 | %windir%\system32\regsvr32.exe /s /u wuaueng.dll
10 | echo =Deleting AU cache...=
11 | del /f /s /q %windir%\SoftwareDistribution\*.*
12 | del /f /s /q %windir%\windowsupdate.log
13 | echo =Registering DLLs...=
14 | %windir%\system32\regsvr32.exe /s %windir%\system32\wuaueng.dll
15 | %windir%\system32\regsvr32.exe /s %windir%\system32\MSXML.DLL
16 | %windir%\system32\regsvr32.exe /s %windir%\system32\MSXML2.DLL
17 | %windir%\system32\regsvr32.exe /s %windir%\system32\MSXML3.DLL
18 | %windir%\system32\regsvr32.exe /s %windir%\system32\wups2.dll
19 | %windir%\system32\regsvr32.exe /s %windir%\system32\wuaueng1.dll
20 | %windir%\system32\regsvr32.exe /s %windir%\system32\wuaueng.dll
21 | %windir%\system32\regsvr32.exe /s %windir%\system32\wuapi.dll
22 | %windir%\system32\regsvr32.exe /s %windir%\system32\atl.dll
23 | %windir%\system32\regsvr32.exe /s %windir%\system32\jscript.dll
24 | %windir%\system32\regsvr32.exe /s %windir%\system32\softpub.dll
25 | %windir%\system32\regsvr32.exe /s %windir%\system32\wuapi.dll
26 | %windir%\system32\regsvr32.exe /s %windir%\system32\wuaueng1.dll
27 | %windir%\system32\regsvr32.exe /s %windir%\system32\wucltui.dll
28 | %windir%\system32\regsvr32.exe /s %windir%\system32\wups.dll
29 | %windir%\system32\regsvr32.exe /s %windir%\system32\wuweb.dll
30 | ECHO =Cleaning registry...=
31 | reg delete HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate /v AccountDomainSid /f
32 | reg delete HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate /v PingID /f
33 | reg delete HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate /v SusClientId /f
34 | reg Delete HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate /v SusClientIDValidation /f
35 | Echo =Starting BITS=
36 | net start bits
37 | ECHO =Starting Windows Update Services=
38 | net start wuauserv
39 | Timeout /t 30 /nobreak
40 | ECHO =Reset Authorisation and Detect now=
41 | wuauclt.exe /resetauthorization /detectnow
42 | usoclient StartScan
43 | Echo =Done...=
44 |
--------------------------------------------------------------------------------
/GPO/get-GPOreport.ps1:
--------------------------------------------------------------------------------
1 | ## Code sniplet from the path - not sure if its work...
2 | $ErrorActionPreference = "Stop"
3 |
4 |
5 | $GPOitem = New-Object psobject
6 | $GPOitem | Add-Member -MemberType NoteProperty -Name 'Policy' -Value $null
7 | $GPOitem | Add-Member -MemberType NoteProperty -Name 'LinkPath' -Value $null
8 | $GPOitem | Add-Member -MemberType NoteProperty -Name 'LinkEnabled' -Value $null
9 | $GPOitem | Add-Member -MemberType NoteProperty -Name 'LinkNoOverride' -Value $null
10 | $result = @{}
11 | try
12 | {
13 | Import-Module grouppolicy
14 | }
15 | catch
16 | {
17 | Write-Warning "GroupPolicy Module ist missing. Please install first" | Out-file $ErrorLog -Append
18 | break
19 | }
20 | $CSV = "\\UNC\Dokumentation\Intern\_Microsoft\GPOReport.CSV"
21 | "Policy, LinkPath, LinkEnabled, LinkNoOverride" | Out-file $CSV -Force
22 |
23 | $GPOS = get-GPO -all
24 | Write-host "Found $($GPOS.count) GPO"
25 | FOREACH ( $GPO in $GPOS)
26 | {
27 | [XML]$GPOv = Get-GPOReport -Name $GPO.DisplayName -ReportType XML
28 | #$GPOv.GPO | Write-Verbose
29 | $m = $GPOv.GPO.LinksTo.count
30 | Write-verbose "$m Links found $($GPO.DisplayName)"
31 | IF ($GPOv.GPO.LinksTo.count -gt 0)
32 | {
33 |
34 | Foreach ($link in $GPOv.GPO.LinksTo)
35 | {
36 |
37 | $GPOitem.Policy= $GPO.DisplayName
38 | $GPOitem.LinkPath= $link.SOMPath
39 | $GPOitem.LinkEnabled= $link.Enabled
40 | $GPOitem.LinkNoOverride= $link.NoOverride
41 | $GPOReport += , $GPOitem
42 | "$($GPO.DisplayName),$($link.SOMPath),$($link.Enabled),$($link.NoOverride)" | Out-file $CSV -Append
43 | }
44 | }
45 | ELSEIF ($GPOv.GPO.LinksTo.count -ne "0")
46 | {
47 | Write-Verbose "Count ne 0"
48 |
49 | $GPOitem.Policy= $GPO.DisplayName
50 | $GPOitem.LinkPath= $GPOv.GPO.LinksTo.SOMPath
51 | $GPOitem.LinkEnabled= $GPOv.GPO.LinksTo.Enabled
52 | $GPOitem.LinkNoOverride= $GPOv.GPO.LinksTo.NoOverride
53 | $GPOReport += , $GPOitem
54 | "$($GPO.DisplayName),$($link.SOMPath),$($link.Enabled),$($link.NoOverride)" | Out-file $CSV -Append
55 | }
56 | ELSE
57 | {
58 | Write-Warning "No Link found $($GPO.DisplayName) $m"
59 | $GPOitem.Policy= $GPO.DisplayName
60 | $GPOReport += , $GPOitem
61 | "$($GPO.DisplayName),,," | Out-file $CSV -Append
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/ActiveDirectory/move-FSMO.ps1:
--------------------------------------------------------------------------------
1 | #requires -version 2.0
2 | #requires -modules activedirectory
3 |
4 | <#
5 | .SYNOPSIS
6 | Move FSMO roles to a new DC
7 | .DESCRIPTION
8 | This script moves FSMO roles to a new single DC.
9 | For more information check https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/fsmo-placement-and-optimization-on-ad-dcs
10 | .EXAMPLE
11 | move-FSMO.ps1 -Server DC -Forest -Domain
12 | .NOTES
13 | Author : Fabian Niesen
14 | Filename : move-FSMO.ps1
15 | Requires : PowerShell Version 2.0
16 |
17 | Version : 0.1
18 | History : 0.1 FN 10.02.2022 initial version
19 |
20 | .LINK
21 | https://gallery.technet.microsoft.com/Gesamtstruktur-Informations-63719eec
22 | #>
23 | [CmdLetBinding()]
24 | param(
25 | [Parameter(Mandatory = $false, Position = 1, ValueFromPipelineByPropertyName = $true,
26 | ValueFromPipeline = $True,
27 | HelpMessage = 'Specify Target Server'
28 | )][Alias("Target")]
29 | [string]$Server,
30 | [switch]$Forest,
31 | [switch]$Domain,
32 | [switch]$All,
33 | [switch]$whatIf
34 | )
35 | Function list-FSMO {
36 | # List actual owner
37 | $forestdata = Get-ADForest
38 | $domaindata = Get-ADDomain
39 | $FSMO = @(@{DomainNamingMaster = $forestdata.DomainNamingMaster; SchemaMaster = $forestdata.SchemaMaster; InfrastructureMaster = $domaindata.InfrastructureMaster; PDCEmulator = $domaindata.PDCEmulator ; RIDMaster = $domaindata.RIDMaster})
40 | $FSMO | ft
41 | }
42 |
43 | If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
44 | {
45 | $arguments = "& '" + $myinvocation.mycommand.definition + "'"
46 | Start-Process powershell -Verb runAs -ArgumentList $arguments
47 | Break
48 | }
49 |
50 | list-FSMO
51 | If ($all)
52 | {
53 | $Forest = $true
54 | $Domain = $true
55 | }
56 | If ($whatIf)
57 | {
58 | If ($Forest) { Write-Output "This would be executed: Move-ADDirectoryServerOperationMasterRole -Identity $Server -OperationMasterRole DomainNamingMaster,SchemaMaster" }
59 | If ($Domain) { Write-Output "This would be executed: Move-ADDirectoryServerOperationMasterRole -Identity $Server -OperationMasterRole RIDMaster,InfrastructureMaster,PDCEmulator" }
60 |
61 | }
62 | ELSE
63 | {
64 | If ($Forest) { Move-ADDirectoryServerOperationMasterRole -Identity $Server -OperationMasterRole DomainNamingMaster,SchemaMaster -Confirm:$false }
65 | If ($Domain) { Move-ADDirectoryServerOperationMasterRole -Identity $Server -OperationMasterRole RIDMaster,InfrastructureMaster,PDCEmulator -Confirm:$false }
66 | }
67 | list-FSMO
68 |
--------------------------------------------------------------------------------
/.github/copilot-instructions.md:
--------------------------------------------------------------------------------
1 | # KI-Agent Anweisungen für Infra-Scripts
2 |
3 | Dieses Repository enthält eine Sammlung von PowerShell-Skripten für die Windows-Infrastrukturverwaltung. Hier sind die wichtigsten Informationen für KI-Agenten:
4 |
5 | ## Projektstruktur
6 |
7 | - Skripte sind nach Funktionsbereichen in Ordnern organisiert (z.B. `ActiveDirectory/`, `BitLocker/`, `WSUS/`)
8 | - Jeder Ordner enthält spezialisierte Skripte für den jeweiligen Bereich
9 | - Hauptverzeichnis enthält allgemeine Verwaltungsskripte
10 |
11 | ## Konventionen
12 |
13 | ### Skript-Reife
14 | - Skripte mit Versionierung im Header sind ausgereifter und besser getestet
15 | - Beispiel aus `GPO/get-GPOBackup.ps1`: Version wird als "V1.58" im Header angegeben
16 |
17 | ### Namenskonventionen
18 | - Verb-Substantiv Benennungsschema (PowerShell-Standard)
19 | - Präfixe zeigen Hauptfunktion:
20 | - `get-` für Abfragen
21 | - `set-` für Konfigurationen
22 | - `install-` für Installationen
23 | - `update-` für Aktualisierungen
24 |
25 | ### Fehlerbehandlung
26 | - PowerShell ErrorAction und Try-Catch Blöcke werden verwendet
27 | - Kritische Operationen haben Sicherheitsabfragen
28 |
29 | ## Hauptkomponenten
30 |
31 | ### Active Directory Management
32 | - Primäre Skripte in `ActiveDirectory/`
33 | - Kernfunktionen: DC-Installation, LAPS-Management, AD-Berechtigungen
34 | - Integration mit Windows-Ereignisprotokollen
35 |
36 | ### BitLocker Verwaltung
37 | - Zentrale Funktionen in `BitLocker/`
38 | - Fokus auf Wiederherstellungsschlüssel-Management und AD-Integration
39 |
40 | ### Gruppenrichtlinien (GPO)
41 | - Backup und Reporting in `GPO/`
42 | - Domänenweite Aktualisierungen
43 | - HTML-Berichterstellung für Dokumentation
44 |
45 | ### Benutzerverwaltung
46 | - Integration mit Microsoft 365
47 | - Automatisierte Benutzerbereitstellung
48 | - Audit und Reporting-Funktionen
49 |
50 | ## Entwicklungs-Workflow
51 |
52 | ### Testing
53 | - Skripte sollten in einer Testumgebung validiert werden
54 | - Parameter `-WhatIf` und `-Confirm` für sensitive Operationen verwenden
55 |
56 | ### Best Practices
57 | - Dokumentiere Änderungen im Skript-Header
58 | - Füge Kommentare für komplexe Operationen hinzu
59 | - Verwende standardisierte PowerShell-Parameter
60 |
61 | ## Wichtige Hinweise
62 |
63 | - Alle Skripte sind "Verwendung auf eigene Gefahr"
64 | - Einige Exchange-Skripte werden nicht mehr aktiv gepflegt
65 | - Bei Microsoft 365-Integration müssen entsprechende Berechtigungen vorhanden sein
66 |
67 | ## Beispiele
68 |
69 | ### GPO-Backup erstellen:
70 | ```powershell
71 | # Erstellt Backup und HTML-Report in timestamp-basiertem Unterordner
72 | .\get-GPOBackup.ps1
73 | ```
74 |
75 | ### BitLocker-Wiederherstellungsschlüssel aktualisieren:
76 | ```powershell
77 | # Lädt fehlende BitLocker-Informationen ins AD hoch
78 | .\Update-BitLockerRecovery.ps1
79 | ```
--------------------------------------------------------------------------------
/install-greenshot.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Install ZIP-Version of GreenShot and create StartMenu entry
4 |
5 | .DESCRIPTION
6 | Install ZIP-Version of GreenShot and create StartMenu entry. This can be used to avoid the open Webpage in the Installer.
7 | The installer also open the Website if it is used with /Verysilent.
8 | This Skript was created for Unattened installation with MDT.
9 |
10 | .EXAMPLE
11 | C:\PS> install-greenshot.ps1
12 |
13 | .NOTES
14 | Author : Fabian Niesen (www.fabian-niesen.de)
15 | Filename : install-greenshot.ps1
16 | Requires : PowerShell Version 3.0
17 | License : The MIT License (MIT)
18 | Copyright (c) 2022-2025 Fabian Niesen
19 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
20 | files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
21 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
22 | furnished to do so, subject to the following conditions:
23 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
24 | The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties
25 | of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be
26 | liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in
27 | connection with the software or the use or other dealings in the Software.
28 | Disclaimer : This script is provided "as is" without warranty. Use at your own risk.
29 | The author assumes no responsibility for any damage or data loss caused by this script.
30 | Test thoroughly in a controlled environment before deploying to production.
31 | Version : 1.1
32 | History : 1.1 FN 03.12.2025 Change License to MIT, housekeeping Header
33 | 1.0 FN 08/07/2019 initial version
34 |
35 | .LINK
36 | https://www.infrastrukturhelden.de
37 | #>
38 | Expand-Archive -Force C:\Programme\Greenshot\Greenshot-NO-INSTALLER-1.2.10.6-RELEASE.zip C:\Programme\Greenshot
39 | Remove-Item C:\Programme\Greenshot\Greenshot-NO-INSTALLER-1.2.10.6-RELEASE.zip
40 | $WshShell = New-Object -comObject WScript.Shell
41 | $Shortcut = $WshShell.CreateShortcut("C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Greenshot.lnk")
42 | $Shortcut.TargetPath = "C:\Programme\Greenshot\Greenshot.exe"
43 | $Shortcut.Save()
--------------------------------------------------------------------------------
/generate-hosts.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Generates a hosts file based on Active Directory
4 | .DESCRIPTION
5 | Generates a hosts file based on Active Directory
6 | .EXAMPLE
7 | C:\PS> Generate-Hosts.ps1
8 |
9 | .EXAMPLE
10 | C:\PS> Generate-Hosts.ps1 -export C:\Temp\hosts
11 |
12 | .PARAMETER export
13 | File path to export the final hosts file
14 |
15 | .NOTES
16 | Author : Fabian Niesen (www.fabian-niesen.de)
17 | Filename : Generate-Hosts.ps1
18 | Requires : PowerShell Version 3.0
19 | Version : 1.1
20 | History : 1.1 FN 03.12.2025 Change License to MIT, housekeeping Header
21 | 1.0 FN 28.09.2022 first official
22 | License : The MIT License (MIT)
23 | Copyright (c) 2022-2025 Fabian Niesen
24 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
25 | files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
26 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
27 | furnished to do so, subject to the following conditions:
28 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
29 | The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties
30 | of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be
31 | liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in
32 | connection with the software or the use or other dealings in the Software.
33 | Disclaimer : This script is provided "as is" without warranty. Use at your own risk.
34 | The author assumes no responsibility for any damage or data loss caused by this script.
35 | Test thoroughly in a controlled environment before deploying to production.
36 |
37 | .LINK
38 | https://github.com/InfrastructureHeroes/Scipts
39 | #>
40 |
41 | Param(
42 | $export = ".\hosts"
43 | )
44 | $scriptversion = "1.1"
45 | Write-Output "Generate-Hosts.ps1 Version $scriptversion "
46 | import-module activedirectory
47 | IF ( Test-Path $export ) { Remove-Item $export -Force -Confirm:$false | out-null }
48 | $Computers = Get-ADComputer -filter "Enabled -eq 'true'" -Properties IPv4Address | Where-Object { $null -ne $_.IPv4Address }
49 | ForEach ($Computer in $Computers)
50 | {
51 | "$($Computer.IPv4Address) $($Computer.Name) $($Computer.DNSHostName)" | Out-File -FilePath $export -Append -Force
52 | }
53 | Get-Content $export
--------------------------------------------------------------------------------
/ActiveDirectory/execute-RemoteScriptWithLAPS.ps1:
--------------------------------------------------------------------------------
1 | #requires -version 4.0
2 | #requires -modules activedirectory
3 | #Requires -RunAsAdministrator
4 | <#
5 | .SYNOPSIS
6 | Execute a remote script with Local Admin account and Microsoft LAPS
7 |
8 | .DESCRIPTION
9 | Execute a remote script with Local Admin account and Microsoft LAPS
10 |
11 | .EXAMPLE
12 | C:\PS> execute-RemoteScriptWirhLAPS.ps1
13 |
14 | .EXAMPLE
15 | C:\PS> execute-RemoteScriptWirhLAPS.ps1
16 |
17 | .PARAMETER computer
18 | Computer to be used as remote target
19 |
20 | .PARAMETER ScriptBlock
21 | ScriptBlock to be executed remotely
22 |
23 | .PARAMETER admin
24 | Name of the Administrative account handled with LAPS
25 |
26 | .NOTES
27 | Author : Fabian Niesen (www.infrastrukturhelden.de)
28 | Filename : execute-RemoteScriptWirhLAPS
29 | Requires : PowerShell Version 4.0
30 | Version : 1.1
31 | History : 1.1 FN 08.09.2022 updated version, translated to english
32 | 1.0.0 FN 04.06.2019 initial version
33 |
34 | .LINK
35 | https://www.infrastrukturhelden.de/microsoft-infrastruktur/active-directory/powershell-skripte-mit-local-administrator-password-solution-laps-nutzen-und-auditieren/
36 | #>
37 |
38 | Param(
39 | [Parameter(Mandatory=$true)][string]$computer, #Computer to which the connection is established
40 | [string]$ScriptBlock,
41 | [string]$admin = "Administrator"
42 | )
43 | #Imports the required module
44 | Import-Module AdmPwd.PS
45 | #User account that is protected with LAPS
46 | $username = "$computer\$admin"
47 | #The readout works only from a shell with administrative rights and an authorized user!
48 | $password = (Get-AdmPwdPassword -ComputerName $computer).Password
49 | IF ( $($password).count -gt 0 ) {
50 | Write-Output "Password was found"
51 | $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username,$($password | ConvertTo-SecureString -asPlainText -Force)
52 | #Create the credentials
53 | $FQDN= $computer + "."+ $(Get-ADDomain).DNSRoot
54 | #To avoid a certificate error the FQDN must be used to establish the connection
55 | IF ($ScriptBlock -ne "")
56 | {
57 | Invoke-Command -ComputerName $FQDN -ScriptBlock { $ScriptBlock } -credential $cred -UseSSL
58 | }
59 | Else
60 | {
61 | Write-Output "No ScriptBlock specified, start demo mode"
62 | Invoke-Command -ComputerName $FQDN -ScriptBlock { Get-ChildItem C:\ } -credential $cred -UseSSL
63 | }
64 | Write-Output "Reset Password timer"
65 | Reset-AdmPwdPassword -ComputerName $computer
66 | #Reset the LAPS password
67 | Write-Output "Give AD replication a few seconds"
68 | Start-Sleep -Seconds 30
69 | #A little patience for local AD replication
70 | Write-Output "Invoke GPupdate on $computer, this may need some minutes to take effect"
71 | Invoke-GPUpdate -Computer $computer -Target Computer -Force
72 | #Run GPUdate to set a new password. This will take a few minutes.
73 | }
74 | else {
75 | Write-Warning "No LAPS Password found"
76 | }
--------------------------------------------------------------------------------
/ActiveDirectory/Get-ADPermissionsReport.ps1:
--------------------------------------------------------------------------------
1 | ##requires -version 5.1
2 | ##requires -modules activedirectory
3 |
4 | <#
5 | .SYNOPSIS
6 | Get CSV Report about all Permisions in Active Directory
7 | .DESCRIPTION
8 | Get CSV Report about all Permisions in Active Directory
9 | .PARAMETER showresult
10 | Shows permissions as Shell output - not recommended
11 | .PARAMETER Export
12 | Activate CSV Export
13 | .PARAMETER Exportpath
14 | Path to CSV file for Export, default: "C:\Temp\$(Get-Date -Format "yyyyMMdd-HHmm")-ADPermissionReport.csv"
15 | .EXAMPLE
16 | Shows permissions as Shell output - not recommended
17 | get-ADPermisionReport.ps1 -showresult
18 | .EXAMPLE
19 | Export report as CSV to c:\temp\ifhpermissionreport.csv
20 | get-ADPermisionReport.ps1 -export -ExportFile c:\temp\ifhpermissionreport.csv
21 | .INPUTS
22 | Keine.
23 | .OUTPUTS
24 | Keine.
25 | .NOTES
26 | Author : Fabian Niesen
27 | Filename : get-ADPermisionReport.ps1
28 | Requires : PowerShell Version 5.1
29 |
30 | Version : 0.2
31 | History : 0.2 FN 28.04.2024 Add Parameters
32 | 0.1 FN 27.04.2024 initial version
33 |
34 | .LINK
35 | https://www.infrastrukturhelden.de
36 | #>
37 | [CmdletBinding(DefaultParameterSetName='showresult')]
38 | Param(
39 | [Parameter(ParameterSetName = "export" ,Mandatory=$false)]
40 | [Parameter(ParameterSetName = "showresult" ,Mandatory=$false)]
41 | [switch]$export,
42 | [Parameter(ParameterSetName = "export" ,Mandatory=$true)]
43 | [string]$ExportFile = "C:\Temp\$(Get-Date -Format "yyyyMMdd-HHmm")-ADPermissionReport.csv",
44 | [Parameter(ParameterSetName = "export" ,Mandatory=$false)]
45 | [Parameter(ParameterSetName = "showresult" ,Mandatory=$false)]
46 | [switch]$showresult
47 | )
48 | # Array for report.
49 | $report = @()
50 | $schemaIDGUID = @{}
51 | # ignore duplicate errors if any #
52 | $ErrorActionPreference = 'SilentlyContinue'
53 | Get-ADObject -SearchBase (Get-ADRootDSE).schemaNamingContext -LDAPFilter '(schemaIDGUID=*)' -Properties name, schemaIDGUID | ForEach-Object {$schemaIDGUID.add([System.GUID]$_.schemaIDGUID,$_.name)}
54 | Get-ADObject -SearchBase "CN=Extended-Rights,$((Get-ADRootDSE).configurationNamingContext)" -LDAPFilter '(objectClass=controlAccessRight)' -Properties name, rightsGUID | ForEach-Object {$schemaIDGUID.add([System.GUID]$_.rightsGUID,$_.name)}
55 | $ErrorActionPreference = 'Continue'
56 | $OUs = (Get-ADOrganizationalUnit -filter *).DistinguishedName
57 | $i = 0
58 | foreach($OU in $OUs){
59 | $i++
60 | Write-Progress -activity "Query Permissions, please wait." -Status "$i of $($OUs.count): $($OU)" -PercentComplete (($i / $OUs.count)*100) -Id 1
61 | $report += Get-Acl -Path "AD:\$OU" | Select-Object -ExpandProperty Access | Select-Object @{name='organizationalunit';expression={$OU}}, @{name='objectTypeName';expression={if ($_.objectType.ToString() -eq '00000000-0000-0000-0000-000000000000') {'All'} Else {$schemaIDGUID.Item($_.objectType)}}}, @{name='inheritedObjectTypeName';expression={$schemaIDGUID.Item($_.inheritedObjectType)}}, *
62 | }
63 | Write-Progress -activity "Query Permissions, please wait." -Completed -Id 1
64 | IF ($showresult) { $report | Format-Table -AutoSize }
65 | IF ($export) { $report | Export-Csv -Path "$ExportFile" -NoTypeInformation -Force -Delimiter ";"}
--------------------------------------------------------------------------------
/User/Get-LastLogonOU.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Scan OU for all users an provide LastLogon for AD and Exchange
4 | .DESCRIPTION
5 | Scan OU for all users an provide LastLogon for AD and Exchange
6 | .EXAMPLE
7 | Get-LastlogonOU.ps1 -OU "OU=Users,DC=Domain,DC=tld" -Export "C:\Export.csv"
8 | .INPUTS
9 | OU: Target OU for scanning
10 | Export: Exportpath for CSV File
11 | .OUTPUTS
12 | Keine.
13 | .NOTES
14 | Author : Fabian Niesen
15 | Requires : PowerShell Version 2.0
16 | License : The MIT License (MIT)
17 | Copyright (c) 2022-2025 Fabian Niesen
18 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
19 | files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
20 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
21 | furnished to do so, subject to the following conditions:
22 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
23 | The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties
24 | of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be
25 | liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in
26 | connection with the software or the use or other dealings in the Software.
27 | Disclaimer : This script is provided "as is" without warranty. Use at your own risk.
28 | The author assumes no responsibility for any damage or data loss caused by this script.
29 | Test thoroughly in a controlled environment before deploying to production.
30 | Version : 0.2 FN 03.12.2025 Changed License to MIT, housekeeping Header
31 | History : 0.1 FN 11.10.2016 initial version
32 |
33 | .LINK
34 |
35 | #>
36 |
37 | [CmdletBinding()]
38 |
39 | Param(
40 | [Parameter(Mandatory=$false, Position=1, ValueFromPipeline=$False)]
41 | [String]$OU="OU=Benutzer-Extern,OU=Bonn,DC=steep,DC=loc",
42 | [Parameter(Mandatory=$false, Position=1, ValueFromPipeline=$False)]
43 | [String]$Export="c:\export.csv"
44 | )
45 | $schriptversion = "0.2"
46 | Write-Output "Get-LastLogonOU.ps1 Version $scriptversion "
47 | $ErrorActionPreference = "SilentlyContinue"
48 | import-module activedirectory
49 | $CSV = @()
50 | Write-Verbose "Ersteller Userliste"
51 | Get-ADUser -SearchBase $OU -filter * -ResultSetSize 5000 -Properties SamAccountName,displayName,lastLogonTimestamp | Sort-Object lastLogonTimestamp |Select-Object SamAccountName,DisplayName,Enabled,@{Name="lastLogonAD"; Expression={[DateTime]::FromFileTime($_.lastLogonTimestamp).ToString('dd.MM.yyyy hh:mm')}} | export-csv $Export -Delimiter ";" -NoTypeInformation -Encoding UTF8
52 | Write-Verbose "Importiere Userliste"
53 | $CSV = Import-CSV -Path $Export -Delimiter ";"
54 | $CSV | Add-Member -MemberType NoteProperty -Name 'ExchangeLastLogon' -Value $null
55 | Write-Verbose "Starte Exchange Abfrage"
56 | ForEach ($Entry in $CSV)
57 | {
58 | $SamAccountName = $Entry.SamAccountName
59 | Write-Verbose "SamAccountName: $SamAccountName "
60 | Try
61 | {
62 | $Entry.ExchangeLastLogon = $(Get-MailboxStatistics $SamAccountName -ErrorAction Stop).LastLogonTime
63 | }
64 | catch
65 | {
66 | $Entry.ExchangeLastLogon = "no Mailbox"
67 | }
68 | }
69 | $CSV | Export-Csv $Export -NoTypeInformation -Delimiter ";" -Encoding UTF8
--------------------------------------------------------------------------------
/ActiveDirectory/Reset-DSRM.ps1:
--------------------------------------------------------------------------------
1 | #requires -version 3.0
2 | #requires -modules activedirectory
3 | #Requires -RunAsAdministrator
4 | <#
5 | .SYNOPSIS
6 | Reset the Directory Services Restore Mode (DSRM) password on a Domain Controller in an Active Directory Domain.
7 | .DESCRIPTION
8 | Reset the Directory Services Restore Mode (DSRM) password on a Domain Controller in an Active Directory Domain.
9 | .EXAMPLE
10 | Reset-DSRM.ps1
11 | .INPUTS
12 | Keine.
13 | .OUTPUTS
14 | Keine.
15 | .PARAMETER
16 | .NOTES
17 | Author : Fabian Niesen
18 | Filename :
19 | Requires : PowerShell Version 3.0
20 | License : GNU General Public License v3 (GPLv3)
21 | (c) 2015-2025 Fabian Niesen, www.infrastrukturhelden.de
22 | This script is licensed under the GNU General Public License v3 (GPLv3), except for 3rd party code (e.g. Function Get-GPPolicyKey).
23 | You can redistribute it and/or modify it under the terms of the GPLv3 as published by the Free Software Foundation.
24 | This script is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
26 | See https://www.gnu.org/licenses/gpl-3.0.html for the full license text.
27 | Version : 0.3
28 | History :
29 | 0.3 FN 25.10.2025 Change License to GPLv3
30 | 0.2 FN 31.08.2022 Add some autodetection, Change Logging
31 | 0.1 FN 26.11.2015 initial version
32 |
33 |
34 | .LINK
35 | https://github.com/InfrastructureHeroes/Scipts/
36 |
37 | .COPYRIGHT
38 | Copyright (c) Fabian Niesen if not stated otherwise. All rights reserved. Licensed under the MIT license.
39 |
40 | #>
41 | [CmdletBinding(DefaultParameterSetName = 'AllDC')]
42 | Param(
43 | [Parameter(Mandatory=$true,
44 | ParameterSetName = 'AllDC',
45 | HelpMessage = 'Reset DSRM on all DCs in Domain')]
46 | [switch]$AllDC,
47 | [Parameter(Mandatory=$true,
48 | ParameterSetName = 'OnlyOne',
49 | HelpMessage = 'Reset DSRM on a single DC')]
50 | [switch]$Server,
51 | [Parameter(Mandatory=$false,
52 | HelpMessage = 'RandomPassword?')]
53 | [switch]$RandomPW,
54 | [Parameter(Mandatory=$false,
55 | HelpMessage = 'Username for Sync Account')]
56 | [string]$Username,
57 | [Parameter(Mandatory=$false,
58 | HelpMessage = 'Password')]
59 | [string]$PW,
60 | [Parameter(Mandatory=$false,
61 | ParameterSetName = 'OnlyOne',
62 | HelpMessage = 'Servername')]
63 | [string]$ServerName,
64 | [string]$logPath = "C:\Windows\System32\LogFiles\"
65 | )
66 | $ErrorActionPreference = "Stop"
67 | IF (RandomPW) {
68 | $TokenSet = @{
69 | U = [Char[]]'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
70 | L = [Char[]]'abcdefghijklmnopqrstuvwxyz'
71 | N = [Char[]]'0123456789'
72 | S = [Char[]]'(~!@#$%^&*_-+=\(){}[]:;<>,.?/)'
73 | }
74 | $Upper = Get-Random -Count 10 -InputObject $TokenSet.U
75 | $Lower = Get-Random -Count 10 -InputObject $TokenSet.L
76 | $Number = Get-Random -Count 7 -InputObject $TokenSet.N
77 | $Special = Get-Random -Count 7 -InputObject $TokenSet.S
78 | $StringSet = $Upper + $Lower + $Number + $Special
79 |
80 | [String]$PW = (Get-Random -Count 30 -InputObject $StringSet) -join ''
81 | }
82 | Write-Host "Please note this Password someware Safe: $PW"
83 | Write-Warning "Be Aware, you need to enter the Password during the execution twice. This can not be automated. Sorry."
84 | #TODO Check User and Create is
85 |
86 | #TODO Set Password
87 |
88 |
89 | If ( $OnlyOne ) {
90 | Try {Test-Connection $ServerName}
91 | catch { Throw "Server $ServerName not reachable!"}
92 | $ntdsutil = ntdsutil "set dsrm password" "reset password on server NULL" q q
93 | } elseif ( $AllDC) {
94 | Write-Host "Not Implemented now"
95 | <# Action when this condition is true #>
96 | } else {
97 | Throw "Please check Script Parameters with get-Help .\Reset-DSRM.PS1"
98 | }
--------------------------------------------------------------------------------
/ActiveDirectory/Locate-46xx.ps1:
--------------------------------------------------------------------------------
1 | #requires -version 2.0
2 | #requires -modules activedirectory
3 |
4 |
5 | <#
6 | .SYNOPSIS
7 | Locate user Lockouts in Active Directory
8 | .DESCRIPTION
9 | Query all DC and Locate user Lockouts in Active Directory within the last 24h. As default the result is shown as Grid-View, but CSV Export is possible.
10 | A lunchtime project...
11 | .EXAMPLE
12 | .\LocateADLockout-v2.ps1 -filter "bn" -CSVOUT $true -Gridview $false -CSVpath
13 | .INPUTS
14 | -filter only DC's with this pattern in the Hostname
15 | -Gridview Output as GridView
16 | -CSVOUT Export as CSV
17 | -CSVpath Exportpath for CSV
18 | .OUTPUTS
19 | Keine.
20 | .NOTES
21 | Author : Fabian Niesen
22 | Filename : Locate-ADLockout.ps1
23 | Requires : PowerShell Version 2.0
24 |
25 | Version : 1.0
26 | History : 1.0
27 |
28 | .LINK
29 | https://www.infrastrukturhelden.de
30 | #>
31 |
32 | Param(
33 | [Parameter(Mandatory=$false, ValueFromPipeline=$True)]
34 | [String]$filter ="*",
35 | [Parameter(Mandatory=$false, ValueFromPipeline=$True)]
36 | [String]$Gridview =$true,
37 | [Parameter(Mandatory=$false, ValueFromPipeline=$True)]
38 | [String]$CSVOUT = $false,
39 | [Parameter(Mandatory=$false, ValueFromPipeline=$True)]
40 | [String]$CSVpath = "changeme"
41 | )
42 |
43 | $LogOuts = @()
44 |
45 |
46 | #@{label=''}, @{label=''},@{label=''}, @{label=''}, @{label=''}
47 | $DCs = Get-ADDomainController -Filter { HostName -like "$filter" }
48 | ForEach ($DC in $DCs)
49 | {
50 | Write-Output "Starte Remote PowerShell Session und Suche nach EventID 4625 zu:" $DC.HostName
51 | $temp = Invoke-Command -ComputerName $DC.HostName -ScriptBlock { Get-EventLog -LogName "Security" -After (Get-Date).AddDays(-1) | Where-Object { $_.EventID -match '4625'} }
52 | ForEach ($t in $temp)
53 | {
54 | IF ($t.ReplacementStrings[7] -like "0xc0000234") { $Staus = "Kontosperrung"} ELSEIF ($t.ReplacementStrings[7] -like "0xc000006d") { $Staus = "Anmelden"}
55 | $Log = New-Object -TypeName psobject
56 | $Log | Add-Member -MemberType NoteProperty -Name EventID -Value $t.EventID
57 | $Log | Add-Member -MemberType NoteProperty -Name TimeGenerated -Value $t.TimeGenerated
58 | $Log | Add-Member -MemberType NoteProperty -Name DC -Value $t.ReplacementStrings[4]
59 | $Log | Add-Member -MemberType NoteProperty -Name Benutzer -Value $($t.ReplacementStrings[6] +"\" +$t.ReplacementStrings[5])
60 | $Log | Add-Member -MemberType NoteProperty -Name Quelle -Value $Staus
61 | $Log | Add-Member -MemberType NoteProperty -Name LoginID -Value $Null
62 | $Log | Add-Member -MemberType NoteProperty -Name IP -Value $t.ReplacementStrings[19]
63 | $Log | Add-Member -MemberType NoteProperty -Name EventServer -Value $DC.HostName
64 | $LogOuts += $Log
65 | }
66 |
67 | Write-Output "Starte Remote PowerShell Session und Suche nach EventID 4776 zu: "$DC.HostName
68 | $temp = Invoke-Command -ComputerName $DC.HostName -ScriptBlock { Get-EventLog -LogName "Security" -After (Get-Date).AddDays(-1) | Where-Object { $_.EventID -match '4776'} }
69 | ForEach ($t in $temp)
70 | {
71 | $Log = New-Object -TypeName psobject
72 | $Log | Add-Member -MemberType NoteProperty -Name EventID -Value $t.EventID
73 | $Log | Add-Member -MemberType NoteProperty -Name TimeGenerated -Value $t.TimeGenerated
74 | $Log | Add-Member -MemberType NoteProperty -Name DC -Value $t.ReplacementStrings[2]
75 | $Log | Add-Member -MemberType NoteProperty -Name Benutzer -Value $t.ReplacementStrings[1]
76 | $Log | Add-Member -MemberType NoteProperty -Name EventServer -Value $DC.HostName
77 | $LogOuts += $Log
78 | }
79 |
80 | }
81 |
82 | IF ($Gridview -eq $true) { $LogOuts | Out-GridView -Title "EventID's 4625 and 4776 on all/filterd DCs" }
83 | IF ($CSVOUT -eq $true)
84 | {
85 | IF ($CSVpath -like "changeme")
86 | {
87 | Write-Verbose "No Path found"
88 | $CSVpath = Read-Host -Prompt "Bitte geben Sie einen Dateinamen inklusive Pfad an"
89 | }
90 | $LogOuts | Export-Csv -Path $CSVpath -Delimiter ";" -NoTypeInformation
91 | }
92 |
93 |
94 |
--------------------------------------------------------------------------------
/Windows/set-cert4rdp.ps1:
--------------------------------------------------------------------------------
1 | #requires -version 5.0
2 | #Requires -RunAsAdministrator
3 |
4 | <#
5 | .SYNOPSIS
6 | Set RDP Certificate based on issuing CA.
7 | .DESCRIPTION
8 | Set RDP Certificate based on issuing CA. Works only if only one Certificate from the Issuing CA is installed.
9 | .EXAMPLE
10 | .\set-cert4rdp.ps1 -caName "Issuing CA"
11 | Set the Cert from the Issuing CA.
12 |
13 | .PARAMETER caName
14 | Name of issung CA
15 |
16 | .NOTES
17 | Author : Fabian Niesen
18 | Filename : .\set-cert4rdp.ps1
19 | Requires : PowerShell Version 5.0
20 | License : The MIT License (MIT)
21 | Copyright (c) 2022-2025 Fabian Niesen
22 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
23 | files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
24 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
25 | furnished to do so, subject to the following conditions:
26 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
27 | The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties
28 | of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be
29 | liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in
30 | connection with the software or the use or other dealings in the Software.
31 | Disclaimer : This script is provided "as is" without warranty. Use at your own risk.
32 | The author assumes no responsibility for any damage or data loss caused by this script.
33 | Test thoroughly in a controlled environment before deploying to production.
34 |
35 | Version : 0.2 FN 03.12.2025 Changed License to MIT, housekeeping Header
36 | History : 0.1 FN 24.09.2024 Initial version.
37 | .LINK
38 | https://github.com/InfrastructureHeroes/Scipts/tree/master/Windows
39 | #>
40 | [cmdletbinding()]
41 | Param(
42 | [string]$caName = ""
43 | )
44 | $scriptversion = "0.2"
45 | Write-Output "set-cert4rdp.ps1 Version $scriptversion "
46 | # Path to the RDP SSL configuration in the registry
47 | $rdpRegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp"
48 |
49 | # Open certificate store (local computer)
50 | $certs = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Issuer -like "*$caName*" }
51 |
52 | if ($certs -and $certs.Count -eq 1) {
53 | # If exactly one certificate was found
54 | $cert = $certs[0]
55 | $thumbprint = $($cert.Thumbprint -replace '\s+', '')
56 | # Add thumbprint in the registry for RDP SSL certificate
57 | Set-ItemProperty -Path $rdpRegPath -Name "SSLCertificateSHA1Hash" -Value ([byte[]]($thumbprint -split '(?<=\G.{2})(?!$)' | ForEach-Object { "0x$_" }))
58 | Write-Output "The thumbprint $thumbprint was successfully entered in the registry."
59 | $cert = Get-ChildItem -Path "Cert:\LocalMachine\My" | Where-Object { $_.Thumbprint -eq $thumbprint }
60 | $keyPath = $cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName
61 | $keyPath = "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\" + $keyPath
62 | # Set permissions for NETWORK SERVICE
63 | $acl = Get-Acl -Path $keyPath
64 | $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("NETWORK SERVICE", "Read", "Allow")
65 | $acl.SetAccessRule($accessRule)
66 | Set-Acl -Path $keyPath -AclObject $acl
67 | Write-Output "Private key permissions have been updated for certificates with thumbprint $thumbprint."
68 | } elseif ($certs.Count -gt 1) {
69 | Write-Output "Several certificates from the CA $caName were found. Please check the certificates."
70 | } else {
71 | Write-Output "No certificate found from the CA $caName."
72 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Infrastrukturhelden.de - English version below
2 | Powershell Skriptsammlung von Fabian Niesen [InfrastrukturHelden.de](https://www.infrastrukturhelden.de). Für alle Scripte gilt:
3 | **Verwendung auf eigene Gefahr und ohne Gewährleistungsansprüche!**
4 | Die Skripte die über einen Header mit Versionierung verfügen, sind meistens ausgereifter. Andere sind teilweise auch nur praktische Codeschnipsel, die ich so besser im Zugriff habe.
5 | Ihr sucht die [Life-Cycle Diagramme](https://github.com/FabianNiesen/InfrastrukturHelden-LifeCycle-diagrams), dann seit Ihr hier leider falsch.
6 |
7 | ## Skripte in der Übersicht
8 |
9 | ### BitLocker
10 | * List-BitLockerrecoveryKeys.ps1 - *Listet alle BitLocker Wiederherstellungsschlüssel im AD auf*
11 | * Update-BitLockerRecovery.ps1 - *Upload BitLocker recovery information to Active Directory, if they not already exist.*
12 | * Start-Bitlocker.ps1 - *Startet die BitLocker Verschlüsselung mit einer definierten PIN*
13 |
14 | ### Exchange
15 | Verschiedene Skripte auf meiner Exchange-Berater Zeit. Nicht mehr gepflegt!
16 |
17 | ### GPO - Gruppenrichtlinien
18 | * get-GPOBackup.ps1 - *Creates backup of the GPO with according html Reports. The script creates a subfolder based upon an actual timestamp. - V1.58*
19 | * invoke-GPupdateDomain.ps1 - *Führt remote ein GPUPDATE für einzelne Computer, OUs oder die ganze Domäne aus*
20 |
21 | ### User - Benutzermanagement
22 | * create-user.ps1 - *Legt einen neuen Benutzer an. Inklusive Microsoft365 Lizenzzuweisung und einer Begrüßungsmail. Passender Artikel: [Benutzer einfachen anlegen mit PowerShell](https://www.infrastrukturhelden.de/microsoft-infrastruktur/active-directory/benutzer-einfachen-anlegen-mit-powershell/)*
23 | * Get-LastLogonOU.ps1 - *zeigt das letzte LogOn für alle Nutzer in einer OU an. Sowohl AD als auch Exchange.*
24 |
25 | ### WSUS - Windows Server Update Service
26 | * decline-WSUSUpdatesTypes.ps1 - *Decline several Update Types in Windows Server Update Services (WSUS)*
27 | * Reset-WSUSClient.cmd - *Setzt diverse Einstellungen auf dem Client zurück. Löst die meisten aller Client Probleme*
28 | * start-WsusServerSync.ps1 - *Startet eine WSUS Syncronisierung über alle Server und schickt eine Email als Abschluss.*
29 |
30 | ### Sonstige
31 | * get-adinfo.ps1 - *Erstellt einen AD Report mit Nützlichen Funktionen wie Liste der DCs und die Versionen des Schemas und eventueller Erweiterungen.*
32 |
33 | [](https://ko-fi.com/Z8Z8FB6VH)
34 | # English version
35 | Powershell script collection by Fabian Niesen [InfrastrukturHelden.de](https://www.infrastrukturhelden.de). The following applies to all scripts:
36 | **Use at your own risk and without any guarantee!**
37 | The scripts that have a header with versioning are usually more mature. Others are sometimes just practical code snippets that I can access better this way.
38 |
39 | ## Scripts in the overview
40 |
41 | ### BitLocker
42 | * List-BitLockerrecoveryKeys.ps1 - *Lists all BitLocker recovery keys in AD*.
43 | * Update-BitLockerRecovery.ps1 - *Upload BitLocker recovery information to Active Directory, if they do not already exist.*
44 | * Start-Bitlocker.ps1 - *Starts BitLocker encryption with a defined PIN*.
45 |
46 | ### Exchange
47 | Scripts from the time where I was Exchange consultant - no longer maintained
48 |
49 | ### GPO - Group Policy
50 | * get-GPOBackup.ps1 - *Creates backup of the GPO with according html reports. The script creates a subfolder based upon an actual timestamp. - V1.58*
51 | * invoke-GPupdateDomain.ps1 - *Remotely executes a GPUPDATE for individual computers, OUs or the entire domain.*
52 |
53 | ### User - User management
54 | * create-user.ps1 - *Creates a new user. Includes Microsoft365 licence assignment and a welcome email. Related Article: [Creating Users Easily with PowerShell](https://www.infrastrukturhelden.de/microsoft-infrastruktur/active-directory/benutzer-einfachen-anlegen-mit-powershell/)*
55 | * Get-LastLogonOU.ps1 - *displays the last logon for all users in an OU. Both AD and Exchange.*
56 |
57 | ### WSUS - Windows Server Update Service
58 | * decline-WSUSUpdatesTypes.ps1 - *Decline several Update Types in Windows Server Update Services (WSUS)*.
59 | * Reset-WSUSClient.cmd - *Resets several settings on the client. Solves most of the client problems*.
60 | * start-WsusServerSync.ps1 - *Starts a WSUS sync across all servers and sends an email as a completion.*
61 |
62 | ### Other
63 | * get-adinfo.ps1 - *Creates an AD report with useful functions like list of DCs and the versions of the schema and any extensions.*
64 |
--------------------------------------------------------------------------------
/Set-Network.ps1:
--------------------------------------------------------------------------------
1 | #requires -version 4.0
2 | #Requires -RunAsAdministrator
3 | <#
4 | .SYNOPSIS
5 | Modify often needed Networkkonfiguration like set DNSDomainName, disable NetBios over TCP/IP or disable IPv6.
6 |
7 | .DESCRIPTION
8 | Modify often needed Networkkonfiguration like set DNSDomainName, disable NetBios over TCP/IP or disable IPv6 based on MS KB929852
9 |
10 | .EXAMPLE
11 | C:\PS> Set-Network.ps1
12 |
13 | .EXAMPLE
14 | C:\PS> Set-Network.ps1
15 |
16 | .PARAMETER DNSDomain
17 | String of the DNSDomain. If used, the DNSDomain will changed and a DNS re-register is triggert.
18 |
19 | .PARAMETER DisableNetbios
20 | Diable NetBios over TCP/IP on all enabled network interfaces
21 |
22 | .PARAMETER DisableIPv6Interfaces
23 | Disable IPv6 on all interfaces and change the prefference to IPv4. Set DisabledComponents to 0x32
24 |
25 |
26 | .COPYRIGHT
27 | Copyright (c) 2022 Fabian Niesen. All rights reserved. Licensed under the MIT license.
28 |
29 | .NOTES
30 | Author : Fabian Niesen (Infrastrukturhelden.de)
31 | Filename : Set-Network.ps1
32 | Requires : PowerShell Version 4.0
33 | License : The MIT License (MIT)
34 | Copyright (c) 2022-2025 Fabian Niesen
35 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
36 | files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
37 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
38 | furnished to do so, subject to the following conditions:
39 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
40 | The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties
41 | of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be
42 | liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in
43 | connection with the software or the use or other dealings in the Software.
44 | Disclaimer : This script is provided "as is" without warranty. Use at your own risk.
45 | The author assumes no responsibility for any damage or data loss caused by this script.
46 | Test thoroughly in a controlled environment before deploying to production.
47 | Version : 1.2
48 | History : 1.2 FN 03.12.2025 Change License to MIT, housekeeping Header
49 | 1.1 FN 11.10.2022 Add Set MTU
50 | 1.0 FN 04.10.2022 extracted from other script for idependent use
51 |
52 | .LINK
53 | https://github.com/InfrastructureHeroes/Scipts
54 | #>
55 |
56 | param (
57 | [string]$DNSDomain,
58 | [switch]$DisableNetbios,
59 | [switch]$DisableIPv6Interfaces,
60 | [int]$MTU = 0
61 |
62 | )
63 | $scriptversion = "1.2"
64 | Write-Output "Set-Network.ps1 Version $scriptversion "
65 | Write-Verbose "DNSDomain: $DNSDomain - DisableNetbios: $DisableNetbios - DisableIPv6Interfaces: $DisableIPv6Interfaces"
66 | Write-Verbose "Scan for Networkinterfaces"
67 | $networkConfig = Get-WmiObject Win32_NetworkAdapterConfiguration -filter "ipenabled = 'true'"
68 | Foreach ( $nc in $networkConfig )
69 | {
70 | $NIPI = Get-NetIPInterface -InterfaceIndex $($nc.InterfaceIndex) -AddressFamily IPv4
71 | IF ( $DNSDomain -ne "")
72 | {
73 | Write-Verbose "Set DNSDomain"
74 | $nc.SetDnsDomain($DNSDomain)
75 | Write-Verbose "Set Dynamic DNS Registration"
76 | $nc.SetDynamicDNSRegistration($true,$true)
77 | ipconfig /registerdns
78 | }
79 | IF ($DisableNetbios)
80 | {
81 | Write-Verbose "Disable NetBios over TCPIP"
82 | $nc.SetTcpipNetbios(2)
83 | }
84 | if ($DisableIPv6Interfaces)
85 | {
86 | Write-Verbose "Disable IPv6 on Interfaces and prefer IPv4 over IPv6 (Based on Microsoft KB929852)"
87 | reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" /v DisabledComponents /t REG_DWORD /d 0x32 /f
88 | }
89 | if ($MTU -ne 0 )
90 | {
91 | Write-Verbose "Set MTU to $MTU is activeatd"
92 | $localMTU = $NIPI.NlMtu
93 | If ( $localMTU -ne $MTU )
94 | {
95 | Set-NetIPInterface -InterfaceIndex $($nc.InterfaceIndex) -NlMtuBytes $MTU -PolicyStore ActiveStore -Confirm:$false
96 | Set-NetIPInterface -InterfaceIndex $($nc.InterfaceIndex) -NlMtuBytes $MTU -PolicyStore PersistentStore -Confirm:$false
97 | #test einbauen
98 | }
99 |
100 | }
101 | }
--------------------------------------------------------------------------------
/send-files.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Small Power Shell script to send files from a directory via mail.
4 |
5 | .DESCRIPTION
6 | Small Power Shell script to send files from a directory via mail and move them into an archive. Each mail contain only a single file. There is a filter for the file type.
7 | This script is designed to be executed as scheduled task.
8 |
9 | .EXAMPLE
10 | send-files.ps1 -sourcepath "C:\User\Fabian\Scaned-PDF" -archivepath "$sourcepath\Archive" -filetype "*.pdf" -SmtpServer mail.infrastrukturhelden.de -From Script@infrastrukturhelden.de -To john.doe@infrastrukturhelden.de
11 |
12 | .PARAMETER sourcepath
13 | Path where to look for files. Subfolders will not be used!
14 |
15 | .PARAMETER archivepath
16 | Path where file will moved after sending
17 |
18 | .PARAMETER filetype
19 | Filter for file types
20 |
21 | .PARAMETER SmtpServer
22 | SmtpServer witch is uses to send the mail
23 |
24 | .PARAMETER From
25 | Mail From
26 |
27 | .PARAMETER To
28 | Mail To
29 |
30 | .PARAMETER Subject
31 | Subject of the Mail
32 |
33 | .PARAMETER SmtpAuth
34 | Switch if SMTP needs authentication
35 |
36 | .PARAMETER smtppw
37 | Password for SMTP User. Only need with SmtpAuth.
38 |
39 | .PARAMETER smtpuser
40 | SMTP Username. Only need with SmtpAuth.
41 |
42 | .PARAMETER SmtpPort
43 | Portnumber for SMTP if non Standard
44 |
45 | .PARAMETER Body
46 | Mail body, no HTML.
47 |
48 | .NOTES
49 | Author : Fabian Niesen
50 | Filename : send-files.ps1
51 | Requires : PowerShell Version 3.0
52 | License : The MIT License (MIT)
53 | Copyright (c) 2022-2025 Fabian Niesen
54 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
55 | files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
56 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
57 | furnished to do so, subject to the following conditions:
58 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
59 | The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties
60 | of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be
61 | liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in
62 | connection with the software or the use or other dealings in the Software.
63 | Disclaimer : This script is provided "as is" without warranty. Use at your own risk.
64 | The author assumes no responsibility for any damage or data loss caused by this script.
65 | Test thoroughly in a controlled environment before deploying to production.
66 | Version : 1.3
67 | History :
68 | 1.3 FN 03.12.2025 Change License to MIT, housekeeping Header
69 | 1.2 FN 25.10.2025 Change License to GPLv3
70 | 1.1 FN 27.08.2022 Add SMTP Port (for #4)
71 | 1.0 FN initial version
72 |
73 | .LINK
74 | https://www.infrastrukturhelden.de/?p=13527
75 | #>
76 | [cmdletbinding()]
77 | Param(
78 | [Parameter(Position=1)]
79 | [string]$sourcepath,
80 | [Parameter(Position=2)]
81 | [string]$archivepath,
82 | [Parameter(Position=3)]
83 | [string]$filetype="*.pdf",
84 | [Parameter(Position=10)]
85 | [string]$SmtpServer,
86 | [Parameter(Position=17)]
87 | [string]$From,
88 | [Parameter(Position=18)]
89 | [string]$To,
90 | [Parameter(Position=19)]
91 | [string]$Subject = "PDF Report: ",
92 | [Parameter(Position=22)]
93 | [switch]$SmtpAuth,
94 | [Parameter(Position=23)]
95 | [string]$smtppw,
96 | [Parameter(Position=24)]
97 | [string]$smtpuser,
98 | [Parameter(Position=25)]
99 | [int]$SmtpPort,
100 | [Parameter(Position=28)]
101 | [string]$Body = "Please see attachment."
102 | )
103 | $schriptversion = "1.3"
104 | Write-Output "send-files.ps1 Version $scriptversion "
105 | IF ($SmtpAuth) {
106 | Write-Debug "Using SMTP Auth"
107 | $password = ConvertTo-SecureString $smtppw -AsPlainText -Force
108 | $cred = New-Object System.Management.Automation.PSCredential ($smtpuser, $password)
109 | }
110 | IF ($SmtpPort) { $SmtpClient.Port = $SmtpPort }
111 | $sources = Get-ChildItem $sourcepath -Filter $filetype -Depth 0
112 |
113 | ForEach ( $source in $sources)
114 | {
115 | $file = $source.FullName
116 | $SubjectM = $Subject + $source.Name
117 | Write-Debug $file
118 | Write-Debug "Send-MailMessage"
119 | IF ($SmtpAuth) { Send-MailMessage -To $To -From $From -Subject $SubjectM -SmtpServer $SmtpServer -Attachments $file -Credential $cred -UseSsl }
120 | ELSE { Send-MailMessage -To $To -From $From -Subject $SubjectM -SmtpServer $SmtpServer -Attachments $file -UseSsl }
121 | Write-Debug "Move File"
122 | Move-Item -Path $file -Destination $archivepath
123 | }
--------------------------------------------------------------------------------
/GPO/invoke-GPupdateDomain.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Execute Invoke-GPupdate for all computers in an OU.
4 |
5 | .DESCRIPTION
6 | Execute Invoke-GPupdate for all computers in an OU with parameters. To speed up the process in larger domains will be a Test-Connection performed before the Invoke-GPupdate.
7 |
8 | .EXAMPLE
9 | C:\PS> invoke-GPupdateDomain.ps1
10 |
11 | .EXAMPLE
12 | C:\PS> invoke-GPupdateDomain.ps1 -SearchBase "OU=Devices,DC=Your,DC=Domain"
13 |
14 | .EXAMPLE
15 | C:\PS> invoke-GPupdateDomain.ps1 -Force
16 |
17 | .EXAMPLE
18 | C:\PS> invoke-GPupdateDomain.ps1 -AsJob
19 |
20 | .EXAMPLE
21 | C:\PS> invoke-GPupdateDomain.ps1 -Computer
22 |
23 | .PARAMETER SearchBase
24 | DN for the AD structure to search for Computers
25 |
26 | .PARAMETER ResultPageSize
27 | Limits the ammout of searched Computer to 1000 in default. Use this parameter to increase if nessessary
28 |
29 | .PARAMETER force
30 | Perform a invoke-gpupdate -Force
31 |
32 | .PARAMETER asjob
33 | Perform a invoke-gpupdate -asjob
34 |
35 | .PARAMETER user
36 | Perform a invoke-gpupdate -target user
37 |
38 | .PARAMETER computer
39 | Perform a invoke-gpupdate -target computer
40 |
41 | .NOTES
42 | Author : Fabian Niesen (infrastrukturhelden.de)
43 | Filename : invoke-GPupdateDomain.ps1
44 | Requires : PowerShell Version 3.0
45 | License : The MIT License (MIT)
46 | Copyright (c) 2022-2025 Fabian Niesen
47 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
48 | files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
49 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
50 | furnished to do so, subject to the following conditions:
51 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
52 | The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties
53 | of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be
54 | liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in
55 | connection with the software or the use or other dealings in the Software.
56 | Disclaimer : This script is provided "as is" without warranty. Use at your own risk.
57 | The author assumes no responsibility for any damage or data loss caused by this script.
58 | Test thoroughly in a controlled environment before deploying to production.
59 | Version : 1.1
60 | History : 1.1 FN 03.12.2025 Changed License to MIT, housekeeping Header
61 | 1.0 FN 10/12/2018 initial version
62 |
63 | .LINK
64 | https://www.infrastrukturhelden.de
65 | #>
66 | Param(
67 | [Parameter(Mandatory=$false, Position=0, ValueFromPipeline=$False)]
68 | [String]$Searchbase="",
69 | [Parameter(Mandatory=$false, Position=1, ValueFromPipeline=$False)]
70 | [int]$ResultPageSize="1000",
71 | [switch]$force,
72 | [switch]$asjob,
73 | [switch]$User,
74 | [switch]$Computer
75 | )
76 | $scriptversion = "1.1"
77 | Write-Output "invoke-GPupdateDomain.ps1 Version $scriptversion "
78 | $ErrorActionPreference = "Stop"
79 | [int]$Suc = 0
80 | $Command = "Invoke-GPupdate "
81 | IF ($force -eq $true) { $Command += "-Force "; Write-Output "Enable Force Mode"}
82 | IF ($asjob -eq $true) { $Command += "-AsJob "; Write-Output "Enable AsJob"}
83 | IF ($User -eq $true -and $Computer -eq $true) {Write-Verbose "There is no need for User and Computer"}
84 | ElseIF ($User -eq $true) { $Command += "-Target User "; Write-Output "Only invoke User Policy"}
85 | ElseIF ($Computer -eq $true) { $Command += "-Target Computer "; Write-Output "Only invoke Computer Policy"}
86 | ELse {Write-Verbose "Run with no Target Scope for GPupdate"}
87 | Write-Verbose "Invoke Command will be: $Command"
88 | Write-Verbose "=== Import AD Module ==="
89 | try
90 | {
91 | Import-Module activedirectory
92 | }
93 | catch
94 | {
95 | Write-Warning "ActiveDirectory Module ist missing. Please install first"
96 | #"GroupPolicy Module ist missing. Please install first" | Out-file $ErrorLog -Append
97 | break
98 | }
99 |
100 | IF ( $Searchbase -eq "") { Write-Verbose "Query Domain DN for Searchbase"; $Searchbase = $(Get-ADDomain).DistinguishedName }
101 | Write-Verbose "Searchbase: $Searchbase"
102 |
103 | $Computers = $(Get-ADComputer -SearchBase $Searchbase -filter {(Enabled -eq $True)} -ResultPageSize $ResultPageSize ).Name
104 | $CompCount = $($Computers.count)
105 | Write-Output "Found $CompCount Computer at $Searchbase"
106 | Write-Progress -activity "Trigger GPupdate" -Status "starting" -PercentComplete "0" -Id 1
107 | [int]$i = "0"
108 | FOREACH ( $Comp in $Computers)
109 | {
110 | $i++
111 | $Try = $true
112 | Write-Progress -activity "Trigger GPupdate" -Status "Active on $Compr" -PercentComplete (($i / $CompCount)*100) -Id 1
113 | Write-Verbose "Test-Connection $Comp"
114 | Try { Test-Connection $Comp -Count 1 -Delay 1 |Out-Null } catch { Write-Warning "Computer $Comp is not reachable."; $Try = $false }
115 | IF ($Try -eq $true)
116 | {
117 | Write-Verbose "Invoke-GPUpdate on $Comp"
118 | $TryGP = $true
119 | Try { $($Command+$Comp) | Out-Null } catch { Write-Warning "Invoke-GPupdate war not successful on $Comp"; $TryGP = $false }
120 | IF ($TryGP -eq $true) {Write-Host -ForegroundColor Green "Invoke-GPupdate on $Comp was successful" ; $Suc++}
121 |
122 | }
123 | }
124 | Write-Verbose "Done"
125 | IF ($asjob -eq $true) {Write-Output "Script was Started in Job mode. There might be still running Jobs" ; Get-Job | FT -AutoSize}
126 | Write-Output "$Suc of $CompCount Computers triggered for GPupdate successful"
--------------------------------------------------------------------------------
/Exchange/Set-Ex2013Vdir.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 |
4 | .DESCRIPTION
5 |
6 | .EXAMPLE
7 |
8 | .INPUTS
9 | Keine.
10 | .OUTPUTS
11 | Keine.
12 | .NOTES
13 | Author : Fabian Niesen
14 | Filename : set-ex2013vdir.ps1
15 | Requires : PowerShell Version 3.0
16 |
17 | Version : 0.1
18 | History :
19 | .LINK
20 |
21 | #>
22 |
23 | Param(
24 | [Parameter(Mandatory=$false, ValueFromPipeline=$False)]
25 | [String]$InternalHost=$null,
26 | [Parameter(Mandatory=$false, ValueFromPipeline=$False)]
27 | [String]$ExternalHost=$null
28 |
29 | )
30 | $before = Get-Date
31 | Set-AdServerSettings -ViewEntireForest $true
32 |
33 | Write-Host "Found the following Exchange Server"
34 | Get-ExchangeServer | ft Name,Site,ServerRole,Edition,AdminDisplayVersion -AutoSize
35 |
36 | IF (!($InternalHost -like "$null"))
37 | {
38 | IF (!($ExternalHost -like "$null"))
39 | {
40 | Write-Host "Set Internalhost $InternalHost and Externalhost $ExternalHost"
41 | Get-ExchangeServer | ? { $_.ServerRole -like "*ClientAccess*" }| Get-WebservicesVirtualDirectory | Set-WebservicesVirtualDirectory -InternalURL https://$InternalHost/EWS/Exchange.asmx -ExternalURL https://$ExternalHost/EWS/Exchange.asmx
42 | Get-ExchangeServer | ? { $_.ServerRole -like "*ClientAccess*" }| Get-OwaVirtualDirectory | Set-OwaVirtualDirectory -InternalURL https://$InternalHost/owa -ExternalURL https://$ExternalHost/owa
43 | Get-ExchangeServer | ? { $_.ServerRole -like "*ClientAccess*" }| Get-ecpVirtualDirectory | Set-ecpVirtualDirectory -InternalURL https://$InternalHost/ecp -ExternalURL https://$ExternalHost/ecp
44 | Get-ExchangeServer | ? { $_.ServerRole -like "*ClientAccess*" }| Get-ActiveSyncVirtualDirectory | Set-ActiveSyncVirtualDirectory -InternalURL https://$InternalHost/Microsoft-Server-ActiveSync -ExternalURL https://$ExternalHost/Microsoft-Server-ActiveSync
45 | Get-ExchangeServer | ? { $_.ServerRole -like "*ClientAccess*" }| Get-OABVirtualDirectory | Set-OABVirtualDirectory -InternalUrl https://$InternalHost/OAB -ExternalURL https://$ExternalHost/OAB
46 | Get-ExchangeServer | ? { $_.ServerRole -like "*ClientAccess*" }| get-mapivirtualdirectory | Set-MapiVirtualDirectory -InternalUrl https://$InternalHost/mapi -ExternalURL https://$ExternalHost/mapi
47 | Get-ExchangeServer | ? { $_.ServerRole -like "*ClientAccess*" }| Set-ClientAccessServer -AutodiscoverServiceInternalUri https://$InternalHost/Autodiscover/Autodiscover.xml
48 | get-OutlookAnywhere | Set-OutlookAnywhere -InternalHostname $InternalHost -ExternalHostName $ExternalHost -InternalClientAuthenticationMethod ntlm -InternalClientsRequireSsl:$True -ExternalClientAuthenticationMethod NTLM -ExternalClientsRequireSsl:$True
49 | }
50 | ELSE
51 | {
52 | Write-Host "Set Internalhost $InternalHost"
53 | Get-ExchangeServer | ? { $_.ServerRole -like "*ClientAccess*" }| Get-WebservicesVirtualDirectory | Set-WebservicesVirtualDirectory -InternalURL https://$InternalHost/EWS/Exchange.asmx -externalurl $null
54 | Get-ExchangeServer | ? { $_.ServerRole -like "*ClientAccess*" }| Get-OwaVirtualDirectory | Set-OwaVirtualDirectory -InternalURL https://$InternalHost/owa -externalurl $null
55 | Get-ExchangeServer | ? { $_.ServerRole -like "*ClientAccess*" }| Get-ecpVirtualDirectory | Set-ecpVirtualDirectory -InternalURL https://$InternalHost/ecp -externalurl $null
56 | Get-ExchangeServer | ? { $_.ServerRole -like "*ClientAccess*" }| Get-ActiveSyncVirtualDirectory | Set-ActiveSyncVirtualDirectory -InternalURL https://$InternalHost/Microsoft-Server-ActiveSync -externalurl $null
57 | Get-ExchangeServer | ? { $_.ServerRole -like "*ClientAccess*" }| Get-OABVirtualDirectory | Set-OABVirtualDirectory -InternalUrl https://$InternalHost/OAB -externalurl $null
58 | Get-ExchangeServer | ? { $_.ServerRole -like "*ClientAccess*" }| get-mapivirtualdirectory | Set-MapiVirtualDirectory -InternalUrl https://$InternalHost/mapi -externalurl $null
59 | Get-ExchangeServer | ? { $_.ServerRole -like "*ClientAccess*" }| Set-ClientAccessServer -AutodiscoverServiceInternalUri https://$InternalHost/Autodiscover/Autodiscover.xml
60 | get-OutlookAnywhere | Set-OutlookAnywhere -InternalHostname $InternalHost -InternalClientAuthenticationMethod ntlm -InternalClientsRequireSsl:$True
61 | }}
62 | ELSE
63 | {
64 | Write-Warning "InternalHost not set, no changes made"
65 | }
66 | Write-Host "Actual Exchange settings"
67 | Write-host "========================"
68 | Write-Host "Autodiscover Uri"
69 | get-exchangeserver | ? { $_.ServerRole -like "*ClientAccess*" }| get-ClientAccessServer | ft Name,AutodiscoverServiceInternalUri,AutoDiscoverSiteScope -AutoSize
70 | Write-Host "OwaVirtualDirectory"
71 | get-exchangeserver | ? { $_.ServerRole -like "*ClientAccess*" }| Get-OwaVirtualDirectory | ft ServerName,Name,ExternalUrl,InternalUrl -AutoSize
72 | Write-Host "EcpVirtualDirectory"
73 | get-exchangeserver | ? { $_.ServerRole -like "*ClientAccess*" }| Get-EcpVirtualDirectory | ft Server,Name,ExternalUrl,InternalUrl,AdminEnabled -AutoSize
74 | Write-Host "OABVirtualDirectory"
75 | get-exchangeserver | ? { $_.ServerRole -like "*ClientAccess*" }| Get-OABVirtualDirectory | ft Server,Name,ExternalUrl,InternalUrl -AutoSize
76 | Write-Host "ActiveSyncVirtualDirectory"
77 | get-exchangeserver | ? { $_.ServerRole -like "*ClientAccess*" }| Get-ActiveSyncVirtualDirectory | ft Server,Name,ExternalUrl,InternalUrl -AutoSize
78 | Write-Host "mapiVirtualDirectory"
79 | get-exchangeserver | ? { $_.ServerRole -like "*ClientAccess*" }| Get-mapiVirtualDirectory | ft Server,Name,ExternalUrl,InternalUrl -AutoSize
80 | Write-Host "WebservicesVirtualDirectory"
81 | get-exchangeserver | ? { $_.ServerRole -like "*ClientAccess*" }| Get-WebservicesVirtualDirectory | ft Server,Name,ExternalUrl,InternalUrl -AutoSize
82 | Write-Host "OutlookAnywhere"
83 | get-exchangeserver | Get-outlookAnywhere | ft Name,ExternalHostname,InternalHostname -AutoSize
84 |
85 | $after = Get-Date
86 |
87 | $time = $after - $before
88 | $buildTime = "`nBuild finished in ";
89 | if ($time.Minutes -gt 0)
90 | {
91 | $buildTime += "{0} minute(s) " -f $time.Minutes;
92 | }
93 |
94 | $buildTime += "{0} second(s)" -f $time.Seconds;
95 | Write-host $buildTime
--------------------------------------------------------------------------------
/Get-WindowsSid.ps1:
--------------------------------------------------------------------------------
1 | #requires -version 5.1
2 |
3 | <#
4 | .SYNOPSIS
5 | Utilize PSGetSid by Mark Russinovich (Sysinternals) to gather the Windows SID from all online Computer within the Active Directory.
6 |
7 | .DESCRIPTION
8 | Utilize PSGetSid by Mark Russinovich (Sysinternals) to gather the Windows SID from all online Computer within the Active Directory. It also gather some Additional information from the Active Directory.
9 | Download and extract PSGetSid from PSTools: https://download.sysinternals.com/files/PSTools.zip
10 | For more details about duplicated SID check Marks article: https://learn.microsoft.com/en-us/archive/blogs/markrussinovich/the-machine-sid-duplication-myth-and-why-sysprep-matters
11 |
12 | .PARAMETER PSGetSid
13 | Path to PsGetsid64.exe including filename
14 |
15 | .PARAMETER CSV
16 | Export report as CSV
17 |
18 | .EXAMPLE
19 | C:\PS> Get-WindowsSid.ps1
20 |
21 | .NOTES
22 | Author : Fabian Niesen (www.fabian-niesen.de)
23 | Filename : Get-WindowsSid.ps1
24 | Requires : PowerShell Version 5.1, PsGetSid from Sysinternals
25 | LastModBy : Fabian Niesen
26 | License : The MIT License (MIT)
27 | Copyright (c) 2022-2025 Fabian Niesen
28 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
29 | files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
30 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
31 | furnished to do so, subject to the following conditions:
32 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
33 | The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties
34 | of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be
35 | liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in
36 | connection with the software or the use or other dealings in the Software.
37 | Disclaimer : This script is provided "as is" without warranty. Use at your own risk.
38 | The author assumes no responsibility for any damage or data loss caused by this script.
39 | Test thoroughly in a controlled environment before deploying to production.
40 |
41 | Version : 1.2
42 | History :
43 | 1.2 FN 03.12.2025 Change License to MIT, housekeeping Header
44 | 1.1 FN 25.10.2025 Change License to GPLv3
45 | 1.0 FN 24.09.2022 first official
46 |
47 | .LINK
48 | https://github.com/InfrastructureHeroes/Scipts
49 | https://www.infrastructureheroes.org/microsoft-infrastructure/microsoft-windows/the-windows-sid-and-an-old-problem/
50 | https://www.infrastrukturhelden.de/microsoft-infrastruktur/microsoft-windows/die-windows-sid-und-ein-altes-problem/
51 | #>
52 |
53 | Param(
54 | [String]$PSGetSid = ".\PsGetsid64.exe",
55 | [switch]$CSV
56 | )
57 |
58 | #ToDo: Test for local PsGetsid64.exe, ask for Path or Download
59 | #ToDo: Add Parameter for CSV Export
60 | #ToDo: Test for PSGetSid exists
61 | $ErrorActionPreference = "SilentlyContinue"
62 | Set-Location $PSScriptRoot
63 | $ScriptName = $myInvocation.MyCommand.Name
64 | $ScriptName = $ScriptName.Substring(0, $scriptName.Length - 4)
65 | $LogName = (Get-Date -UFormat "%Y%m%d-%H%M") + "-" + $scriptName + "_" + $ENV:COMPUTERNAME +".log"
66 | Start-Transcript -Path "$PSScriptRoot\$LogName" -Append
67 |
68 | try {
69 | Get-ItemProperty -Path "REGISTRY::HKEY_CURRENT_USER\Software\Sysinternals\PsGetSid" -ErrorAction Stop | Select-Object -ExpandProperty "EulaAccepted" -ErrorAction Stop | Out-Null
70 | }
71 | catch {
72 | Write-Verbose "no EULA"
73 | $accepteula = Read-Host "Do you Accept the EULA? (Y/N)"
74 | IF ( $accepteula -match "y" -or $accepteula -match "z")
75 | { & $PSGetSid -accepteula }
76 | ELSE { Break }
77 | }
78 | $Computers = Get-ADComputer -Filter "Enabled -eq 'true'" -Properties name,LastLogonDate,OperatingSystem,OperatingSystemVersion,whenChanged,DNSHostName | Sort-Object | Select-Object name,LastLogonDate,OperatingSystem,OperatingSystemVersion,whenChanged,DNSHostName
79 | $Computers | Add-Member -MemberType NoteProperty -Name 'SID' -Value $null
80 | $Computers | Add-Member -MemberType NoteProperty -Name 'Online' -Value $null
81 | $SIDs = @()
82 | $SIDs | Add-Member -MemberType NoteProperty -Name 'Online' -Value $null
83 | $SIDs | Add-Member -MemberType NoteProperty -Name 'SID' -Value $null
84 | Write-Progress -activity "Processing PSsid" -Status "starting" -PercentComplete "0" -Id 1
85 | [int]$i = 0
86 | [int]$j = $($Computers).count
87 | ForEach ($Computer in $Computers)
88 | {
89 | Write-Progress -activity "Processing PSsid - $i of $j" -Status "$($Computer.name)" -PercentComplete (($i / $j *100)) -Id 1 -ErrorAction SilentlyContinue
90 | $i++
91 | [bool]$Computer.Online = [bool]$(Test-Connection $($Computer.DNSHostName) -Count 3 -ErrorAction SilentlyContinue)
92 | IF ( $($Computer.Online) -eq $true)
93 | {
94 | Write-Verbose "$($Computer.DNSHostName) - Starte PSSID"
95 | $pssid = (& $PSGetSid \\$($Computer.name) -nobanner) | Select-String -Pattern "S-1-5-21-"
96 | $Computer.SID = $pssid
97 | } ELSEIF ( $($Computer.Online) -eq $false) {
98 | Write-Verbose "$($Computer.DNSHostName) - System Offline"
99 | } Else { Write-host "WTF $($Computer.DNSHostName)" }
100 | Write-Verbose "Value: $Computer"
101 | $SIDs += $Computer
102 | }
103 | $SIDs | Format-Table -Property name,Online,SID,LastLogonDate,OperatingSystem,OperatingSystemVersion,whenChanged -AutoSize
104 | IF ( $CSV)
105 | {
106 | $csvpath = "$PSScriptRoot\"+(Get-Date -UFormat "%Y%m%d-%H%M")+"-SID.csv"
107 | Write-Output "CSV file generated - $csvpath"
108 | $SIDs | Export-Csv -Path $csvpath -Force -Delimiter ";" -NoTypeInformation
109 | }
--------------------------------------------------------------------------------
/GPO/Check-LocalGroupPolicy.ps1:
--------------------------------------------------------------------------------
1 | #requires -version 4.0
2 | #Requires -RunAsAdministrator
3 | <#
4 | .SYNOPSIS
5 | Check local EventLog for signes of issues with Local GPO and fixed them if needed.
6 | .DESCRIPTION
7 | Check local EventLog for signes of issues with Local GPO and fixed them if needed. Malformed local GPO prevent GPO processing. This mean changes in GPOs will not be processed by this client. The script needs to be run with Administrative permissions.
8 | .EXAMPLE
9 | Check-LocalGroupPolicy.ps1
10 |
11 | .NOTES
12 | Author : Fabian Niesen
13 | Filename : Check-LocalGroupPolicy.ps1
14 | Requires : PowerShell Version 4.0
15 | License : The MIT License (MIT)
16 | Copyright (c) 2022-2025 Fabian Niesen
17 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
18 | files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
19 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
20 | furnished to do so, subject to the following conditions:
21 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
22 | The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties
23 | of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be
24 | liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in
25 | connection with the software or the use or other dealings in the Software.
26 | Disclaimer : This script is provided "as is" without warranty. Use at your own risk.
27 | The author assumes no responsibility for any damage or data loss caused by this script.
28 | Test thoroughly in a controlled environment before deploying to production.
29 | Version : 0.4
30 | History : 0.4 03.12.2025 FN Changed License to MIT, housekeeping Header
31 | 0.3 23.12.2022 FN Some Cleanup and Housekeeping
32 | 0.2 08.03.2021 FN Found in personal archive and published to GitHub
33 | 0.1 FN 2016 Initial version.
34 | .LINK
35 | https://github.com/InfrastructureHeroes/Scipts/blob/master/GPO/Check-LocalGroupPolicy.ps1
36 | #>
37 | [cmdletbinding()]
38 | Param(
39 | [Parameter(Mandatory=$false, Position=2, ValueFromPipeline=$False)]
40 | [bool]$needfix = $false,
41 | [Parameter(Mandatory=$false, Position=1, ValueFromPipeline=$False)]
42 | $logpath = "C:\Windows\System32\LogFiles\"
43 | )
44 | $scriptversion = "0.4"
45 | Write-Output "Check-LocalGroupPolicy.ps1 Version $scriptversion "
46 | $ScriptName = $myInvocation.MyCommand.Name
47 | $ScriptName = $ScriptName.Substring(0, $ScriptName.Length - 4)
48 | $LogName = $ScriptName + "_" + $env:computername + "_" + (Get-Date -UFormat "%Y%m%d") + ".log"
49 | $logfile = $logpath + $LogName
50 | "$(get-date -format yyyyMMdd-HHmm) Starting $ScriptName" | Out-File $logfile -Append
51 | # Function to start a CLI application and return the exit code - This could maybe also be done with Invoke-GPUpdate today, but I have no malformed device to test.
52 | # Based upon https://powersheller.wordpress.com/2011/03/29/powershell-re-creating-the-local-group-policy-database-file/
53 | Function Start-CliApplication {
54 | param ( [string]$application, [string]$arguments )
55 | # Build Startinfo and set options according to parameters
56 | $startInfo = new-object System.Diagnostics.ProcessStartInfo
57 | $startInfo.FileName = $application
58 | $startInfo.Arguments = $arguments
59 | $startInfo.WindowStyle = "Hidden"
60 | $startInfo.CreateNoWindow = $true
61 | $startInfo.UseShellExecute = $false
62 | # Start the process
63 | $process = [System.Diagnostics.Process]::Start($startinfo)
64 |
65 | # Wait until the process finished
66 | Do {
67 | If( -not $process.HasExited ) {
68 | $process.Refresh()
69 | }
70 | } While( -not $process.WaitForExit(1000) )
71 |
72 | # Output the exitcode
73 | Write-Output $process.exitcode
74 | }
75 |
76 | "$(get-date -format yyyyMMdd-HHmm) Processing Eventlog" | Out-File $logfile -Append
77 |
78 | $eventGpoProcessingFailed = Get-EventLog System -Newest 500 | where { $_.eventID -eq "1096" }
79 |
80 | IF ( $eventGpoProcessingFailed -ne $null)
81 | {
82 | "$(get-date -format yyyyMMdd-HHmm) Found EventID 1096"| Out-File $logfile -Append
83 | $FilePath = $($eventGpoProcessingFailed[0] | select -ExpandProperty ReplacementStrings)[8]
84 | "$(get-date -format yyyyMMdd-HHmm) Find corupted local GPO: $FilePath" | Out-File $logfile -Append
85 | "$(get-date -format yyyyMMdd-HHmm) Set NeedFix"| Out-File $logfile -Append
86 | $needfix = $true
87 | }
88 |
89 | IF ( $needfix -eq $true)
90 | {
91 | "$(get-date -format yyyyMMdd-HHmm) Fix required, Try to delete File: $FilePath"| Out-File $logfile -Append
92 | Remove-Item -LiteralPath $FilePath -Force
93 | "$(get-date -format yyyyMMdd-HHmm) Test if file is deleted"| Out-File $logfile -Append
94 | IF ( !(Test-Path $FilePath))
95 | {
96 | "$(get-date -format yyyyMMdd-HHmm) File removed, starting GPUPDATE"| Out-File $logfile -Append
97 | Start-Sleep -Seconds 5
98 | $gpupdateResult = Start-CliApplication "gpupdate" "/force"
99 | If ($gpUpdateResult -eq 0)
100 | {
101 | "$(get-date -format yyyyMMdd-HHmm) Group Policy Update Successful"| Out-File $logfile -Append
102 | }
103 | Else
104 | {
105 | "$(get-date -format yyyyMMdd-HHmm) Group Policy Update Failed"| Out-File $logfile -Append
106 | break
107 | }
108 | }
109 | ELSE
110 | {
111 | "$(get-date -format yyyyMMdd-HHmm) Can not remove $FilePath, please check"| Out-File $logfile -Append
112 | break
113 | }
114 | }
115 | ELSE {"$(get-date -format yyyyMMdd-HHmm) Noting to do"| Out-File $logfile -Append }
116 |
--------------------------------------------------------------------------------
/Set-WinRelease.ps1:
--------------------------------------------------------------------------------
1 | #Requires -RunAsAdministrator
2 |
3 | <#
4 | .SYNOPSIS
5 | Set Registry key to stay at a specific Windows 10 Release
6 |
7 | .DESCRIPTION
8 | Set Registry key to set a max Windows 10 Release version for Windows update automatic feature upgrade. This script does not force a downgrade.
9 | Use it on your own risk.
10 |
11 | .EXAMPLE
12 | C:\PS> set-WinRelease.ps1
13 |
14 | .EXAMPLE
15 | C:\PS> set-WinRelease.ps1 -ver 1909
16 |
17 | .PARAMETER ver
18 | Set Windows Release to this version
19 |
20 | .NOTES
21 | Author : Fabian Niesen (www.infrastrukturhelden.de)
22 | Filename : set-WinRelease.ps1
23 | Requires : PowerShell Version 3.0
24 | License : The MIT License (MIT)
25 | Copyright (c) 2022-2025 Fabian Niesen
26 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
27 | files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
28 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
29 | furnished to do so, subject to the following conditions:
30 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
31 | The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties
32 | of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be
33 | liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in
34 | connection with the software or the use or other dealings in the Software.
35 | Disclaimer : This script is provided "as is" without warranty. Use at your own risk.
36 | The author assumes no responsibility for any damage or data loss caused by this script.
37 | Test thoroughly in a controlled environment before deploying to production.
38 | Version : 1.1
39 | History : 1.1 FN 30.05.2024 Added 23H2 and 24H2, MIT License, housekeeping Header
40 | 1.0 FN 30.11.2021 initial version
41 |
42 | .LINK
43 | https://github.com/InfrastructureHeroes/Scipts
44 | #>
45 |
46 | Param(
47 | [Parameter(Mandatory=$true)][ValidateSet("1909","2004","20H2","21H1","21H2","22H2","23H2","24H2")] [string]$ver
48 | )
49 | $scriptversion = "1.1"
50 | Write-Output "Set-WinRelease.ps1 Version $scriptversion "
51 | $ErrorActionPreference = "Stop"
52 | $RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Update"
53 | $RegName = "TargetReleaseVersion"
54 | $RegValue = "1"
55 | $ProductName = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name ProductName).ProductName
56 | If ( $ProductName -Like "Windows 10 Pro") { $Edition = "Pro"}
57 | elseif ( $ProductName -like "Windows 10 Enterprise") { $Edition = "Ent"}
58 | else { $Edition = "Other" }
59 |
60 | Try { $Version = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name ReleaseID -ErrorAction Stop).ReleaseID }
61 | Catch { $Version = "N/A" }
62 | Write-Output "Found $ProductName"
63 | if ($ver -eq $null) { Write-Output "No Windows Release selected, please start again with the release of choice." ; Break }
64 | If (-NOT (Test-Path $RegPath)) { New-Item -Path $RegPath -Force | Out-Null }
65 | New-ItemProperty -Path $RegPath -Name $RegName -Value $RegValue -PropertyType DWORD -Force
66 | $RegName = "TargetReleaseVersionInfo"
67 | $date = Get-Date
68 | Switch ( $ver )
69 | {
70 | "21H2"
71 | {
72 | New-ItemProperty -Path $RegPath -Name $RegName -Value "21H2" -PropertyType String -Force
73 | If ( $Edition -like "Pro") { $sdate = get-date -Year "2023" -Month "06" -Day "13" ; If ($date -gt $sdate) { Write-Warning "$ProductName $Version is not longer supported anymore!!"} ELSE { $left = $($sdate - $date).Days ; Write-Output "You have $left days support left till EOL for $ProductName $ver" } }
74 | ElseIf ( $Edition -like "Ent") { $sdate = get-date -Year "2024" -Month "06" -Day "11" ; If ($(get-date) -gt $sdate) { Write-Warning "$ProductName $Version is not longer supported anymore!!"} ELSE { $left = $($sdate - $date).Days ; Write-Output "You have $left days support left till EOL for $ProductName $ver" } }
75 | }
76 | "21H1"
77 | {
78 | New-ItemProperty -Path $RegPath -Name $RegName -Value "21H1" -PropertyType String -Force
79 | $sdate = get-date -Year "2022" -Month "12" -Day "13"
80 | If ($( get-date) -gt $sdate) { Write-Warning "$ProductName $Version is not longer supported anymore!!"} ELSE { $left = $($sdate - $date).Days ; Write-Output "You have $left days support left till EOL for $ProductName $ver" }
81 | }
82 | "20H2"
83 | {
84 | New-ItemProperty -Path $RegPath -Name $RegName -Value "20H2" -PropertyType String -Force
85 | If ( $Edition -like "Pro") {$sdate = get-date -Year "2022" -Month "05" -Day "10" ; If ($( get-date) -gt $sdate) { Write-Warning "$ProductName $Version is not longer supported anymore!!"} ELSE { $left = $($sdate - $date).Days ; Write-Output "You have $left days support left till EOL for $ProductName $ver" } }
86 | ElseIf ( $Edition -like "Ent") { $sdate = get-date -Year "2023" -Month "05" -Day "09" ; If ($(get-date) -gt $sdate) { Write-Warning "$ProductName $Version is not longer supported anymore!!"} ELSE { $left = $($sdate - $date).Days ; Write-Output "You have $left days support left till EOL for $ProductName $ver" } }
87 | }
88 | "2004"
89 | {
90 | New-ItemProperty -Path $RegPath -Name $RegName -Value "2004" -PropertyType String -Force
91 | $sdate = get-date -Year "2021" -Month "12" -Day "14"
92 | If ($( get-date) -gt $sdate) { Write-Warning "$ProductName $Version is not longer supported anymore!!"} ELSE { $left = $($sdate - $date).Days ; Write-Output "You have $left days support left till EOL for $ProductName $ver" }
93 | }
94 | "1909"
95 | {
96 | New-ItemProperty -Path $RegPath -Name $RegName -Value "1909" -PropertyType String -Force
97 | If ( $Edition -like "Pro") { $sdate = get-date -Year "2021" -Month "05" -Day "10" ; If ($( get-date) -gt $sdate) { Write-Warning "$ProductName $Version is not longer supported anymore!!"} ELSE { $left = $($sdate - $date).Days ; Write-Output "You have $left days support left till EOL for $ProductName $ver" }}
98 | ElseIf ( $Edition -like "Ent") { $sdate = get-date -Year "2022" -Month "05" -Day "11" ; If ($(get-date) -gt $sdate) { Write-Warning "$ProductName $Version is not longer supported anymore!!"} ELSE { $left = $($sdate - $date).Days ; Write-Output "You have $left days support left till EOL for $ProductName $ver" }}
99 | }
100 | Default { Write-Warning "No valid Value entered. Please use 21H2, 21H1, 2004 or 1909" }
101 | }
102 |
--------------------------------------------------------------------------------
/User/create-user.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Code sample to create a new AD User with Office 365 integration.
4 |
5 | .DESCRIPTION
6 | Code sample to create a new AD User with Office 365 integration. This needs to be customized to the target environment.
7 |
8 | .NOTES
9 | Author : Fabian Niesen (infrastrukturhelden.de)
10 | Filename : create-user.ps1
11 | Requires : PowerShell Version 3.0
12 |
13 | Version : 0.3
14 | History : 0.3 FN 03.12.2025 Changed License to MIT, housekeeping Header
15 | 0.2 FN 27.08.2022 Add SmtpPort due #4, fixed some encoding and Typos - Not testest, since my test env is down - Any problems, open an issue at https://github.com/InfrastructureHeroes/Scipts
16 | 0.1 FN 22.01.2019 initial draft
17 | License : The MIT License (MIT)
18 | Copyright (c) 2022-2025 Fabian Niesen
19 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
20 | files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
21 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
22 | furnished to do so, subject to the following conditions:
23 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
24 | The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties
25 | of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be
26 | liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in
27 | connection with the software or the use or other dealings in the Software.
28 | Disclaimer : This script is provided "as is" without warranty. Use at your own risk.
29 | The author assumes no responsibility for any damage or data loss caused by this script.
30 | Test thoroughly in a controlled environment before deploying to production.
31 | .LINK
32 | https://www.infrastrukturhelden.de/microsoft-infrastruktur/active-directory/benutzer-einfachen-anlegen-mit-powershell/
33 | https://github.com/InfrastructureHeroes/Scipts/blob/master/User/create-user.ps1
34 | #>
35 |
36 | [cmdletbinding()]
37 | Param(
38 | [string] $OU="OU=Benutzer,DC=ADG,DC=local",
39 | [string] $Vorname="",
40 | [string] $Nachname="",
41 | [string] $Password="Pa$$w0rd!1",
42 | [string] $Username=$Vorname+"."+$Nachname ,
43 | [string] $Email="demo.held@niesenf.onmicrosoft.com",
44 | [string] $UPN="demo.held@adg.local",
45 | [switch] $PWwechsel,
46 | [switch] $Aktiviert,
47 | [DateTime] $Ablaufdatum, #-AccountExpirationDate #! Umsetzen
48 | [switch] $O365,
49 | [string] $ADCServer="",
50 | [String] $O365Loc="",
51 | [String] $O365Lic="SPE_E5", #Office365 E3 Development = DEVELOPERPACK, Microsoft365 E5 = SPE_E5, WDATP = WIN_DEF_ATP
52 | [string] $DC="",
53 | [string] $Abt="",
54 | [string] $SmtpServer,
55 | [string] $From,
56 | [string] $To,
57 | [switch] $TLS,
58 | [switch] $SmtpAuth,
59 | [string] $smtppw = "",
60 | [string] $smtpuser = "",
61 | [int] $SmtpPort =""
62 | )
63 | $scriptversion = "0.3"
64 | Write-Output "create-user.ps1 Version $scriptversion "
65 | [String] $WelcomeSub = "Willkommen bei Infrastrukturhelden.de"
66 | [String] $WelcomeBody = "Hallo $Vorname" + ',
hier schreiben wir dir noch eine nette Begrüssung
Besuche uns auf Infrastrukturhelden.de'
67 |
68 | Function SendEmailStatus($From, $To, $Subject, $SmtpServer, $BodyAsHtml, $Body)
69 | {
70 | $SmtpMessage = New-Object System.Net.Mail.MailMessage $From, $To, $Subject, $Body
71 | $SmtpMessage.IsBodyHTML = $BodyAsHtml
72 | $SmtpClient = New-Object System.Net.Mail.SmtpClient $SmtpServer
73 | IF ($TLS) { $SmtpClient.EnableSsl = $true }
74 | IF ($SmtpAuth) { $SmtpClient.Credentials = New-Object System.Net.NetworkCredential($smtpuser, $smtppw) }
75 | IF ($SmtpPort) { $SmtpClient.Port = $SmtpPort }
76 | $SmtpClient.Send($SmtpMessage)
77 | If($? -eq $False){Write-Warning "$($Error[0].Exception.Message) | $($Error[0].Exception.GetBaseException().Message)"}
78 | $SmtpMessage.Dispose()
79 | Remove-Variable SmtpClient
80 | Remove-Variable SmtpMessage
81 | }
82 | If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole( [Security.Principal.WindowsBuiltInRole] "Administrator"))
83 | {
84 | $newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
85 | $newProcess.Arguments = $myInvocation.MyCommand.Definition;
86 | $newProcess.Verb = "runas";
87 | break
88 | }
89 | if(@(get-module | where-object {$_.Name -eq "ActiveDirectory"} ).count -eq 0) {import-module ActiveDirectory}
90 | Import-Module ActiveDirectory
91 | IF ($DC -eq "") { $DC = $(Get-ADDomainController).HostName ; Write-Verbose "Kein DC angegeben, nutze $DC" }
92 | IF ( $O365 ) { Try { Connect-AzureAD } catch { Write-Verbose "Installiere AzureAD Modul" ; Install-Module -Name AzureAD -Force ; Connect-AzureAD } }
93 | $SecPass = $Password | ConvertTo-SecureString -AsPlainText -Force
94 | #Zeichenlimit für SAM Account
95 | Write-Verbose "Lege Benutzer an"
96 | New-ADUser -Name $Username -GivenName $Vorname -Surname $Nachname -Path $OU -AccountPassword $SecPass -DisplayName $($Vorname+" "+$Nachname) -EmailAddress $Email -UserPrincipalName $UPN -OtherAttributes @{proxyAddresses=$("SMPT:"+$Email)} -Server $DC
97 | Start-Sleep -Seconds 10
98 | IF ( $PWwechsel ) { Set-ADUser -Identity $Username -ChangePasswordAtLogon $true -Server $DC } ELSE { Set-ADUser -Identity $Username -ChangePasswordAtLogon $false -Server $DC }
99 | IF ( $Aktiviert ) { Set-ADUser -Identity $Username -Enabled $true -Server $DC ; Write-Verbose "Aktiviere $Username" }
100 | IF ( $Abt -eq "" ) { Write-verbose "Keine Abteilung ausgewählt" } Else { Add-ADGroupMember -Identity $Abt -Members $Username }
101 | IF ( $O365 ) {
102 | Write-Verbose "Starte AAD Sync"
103 | Invoke-Command -ComputerName $ADCServer -ScriptBlock { Start-ADSyncSyncCycle -PolicyType Delta }
104 | while ( $(try {Get-AzureADUser -ObjectId $Email} catch {}).count -lt 1) { start-sleep -Seconds 10 ; Write-Verbose "Wait for user appear online"}
105 | #Lizenzzuweisen
106 | Set-AzureADUser -ObjectId $Email -UsageLocation "DE"
107 | $license = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicense
108 | $licenses = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
109 | $license.SkuId = (Get-AzureADSubscribedSku | Where-Object -Property SkuPartNumber -Value $O365Lic -EQ).SkuID
110 | $licenses.AddLicenses = $license
111 | Set-AzureADUserLicense -ObjectId $Email -AssignedLicenses $licenses
112 | Write-Verbose "Assigned Licenses: $($(Get-AzureADUserLicenseDetail -ObjectId $Email ).SkuPartNumber)"
113 | }
114 | # Willkommensemail
115 | SendEmailStatus -From $From -To $Email -Subject $WelcomeSub -SmtpServer $SmtpServer -BodyAsHtml $True -Body $WelcomeBody
--------------------------------------------------------------------------------
/Windows/Remove-AzureArc.ps1:
--------------------------------------------------------------------------------
1 | #requires -version 5.1
2 |
3 | <#
4 | .SYNOPSIS
5 | Remove Azure Arc Setup if installed. Reboot will happend automaticaly.
6 |
7 | .DESCRIPTION
8 | Remove Azure Arc Setup if installed. Reboot will happend automaticaly.
9 |
10 | .EXAMPLE
11 | Remove-AzureArc.ps1
12 |
13 | .NOTES
14 | Author : Fabian Niesen
15 | Filename : Remove-AzureArc.ps1
16 | Requires : PowerShell Version 5.1
17 | License : The MIT License (MIT)
18 | Copyright (c) 2024-2025 Fabian Niesen
19 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
20 | files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
21 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
22 | furnished to do so, subject to the following conditions:
23 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
24 | The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties
25 | of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be
26 | liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in
27 | connection with the software or the use or other dealings in the Software.
28 | Disclaimer : This script is provided "as is" without warranty. Use at your own risk.
29 | The author assumes no responsibility for any damage or data loss caused by this script.
30 | Test thoroughly in a controlled environment before deploying to production.
31 | Version : 1.1 FN 03.12.2025 Changed License to MIT, housekeeping Header
32 | History : FN 06.03.2024 Initiale Version
33 | .LINK
34 | https://github.com/InfrastructureHeroes/Scipts
35 | #>
36 |
37 | #REGION Functions
38 | Function Get-PendingRebootStatus {
39 | <#
40 | .Synopsis
41 | This will check to see if a server or computer has a reboot pending.
42 | For updated help and examples refer to -Online version.
43 |
44 | .NOTES
45 | Name: Get-PendingRebootStatus
46 | Author: theSysadminChannel, Fabian Niesen
47 | Version: 1.2 FN
48 | DateCreated: 2018-Jun-6
49 | DateModified: 2023-Jan-20
50 |
51 | .LINK
52 | https://thesysadminchannel.com/remotely-check-pending-reboot-status-powershell
53 |
54 |
55 | .PARAMETER ComputerName
56 | By default it will check the local computer.
57 |
58 | .EXAMPLE
59 | Get-PendingRebootStatus -ComputerName PAC-DC01, PAC-WIN1001
60 |
61 | Description:
62 | Check the computers PAC-DC01 and PAC-WIN1001 if there are any pending reboots.
63 | #>
64 |
65 | [CmdletBinding()]
66 | Param ()
67 |
68 | BEGIN {}
69 |
70 | PROCESS {
71 | Try {
72 | $Computer = $env:COMPUTERNAME
73 | $PendingReboot = $false
74 | $HKLM = [UInt32] "0x80000002"
75 | $WMI_Reg = [WMIClass] "\\$Computer\root\default:StdRegProv"
76 | if ($WMI_Reg) {
77 | if (($WMI_Reg.EnumKey($HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\")).sNames -contains 'RebootPending') {$PendingReboot = $true ; Write-output "Component Based Servicing: RebootPending"}
78 | if (($WMI_Reg.EnumKey($HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\")).sNames -contains 'RebootRequired') {$PendingReboot = $true ; Write-output "WindowsUpdate: RebootRequired"}
79 | if (($WMI_Reg.EnumKey($HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager")).sNames -contains 'PendingFileRenameOperations') {$PendingReboot = $true ; Write-output "Session Manager: PendingFileRenameOperations"}
80 | if (($WMI_Reg.EnumKey($HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update")).sNames -contains 'PostRebootReporting') {$PendingReboot = $true ; Write-output "WindowsUpdate: PostRebootReporting"}
81 | if (($WMI_Reg.EnumKey($HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager")).sNames -contains 'PendingFileRenameOperations2') {$PendingReboot = $true ; Write-output "Session Manager: PendingFileRenameOperations2"}
82 | if (($WMI_Reg.EnumKey($HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\")).sNames -contains 'RebootInProgress') {$PendingReboot = $true ; Write-output "Component Based Servicing: RebootInProgress"}
83 | if (($WMI_Reg.EnumKey($HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\")).sNames -contains 'PackagesPending') {$PendingReboot = $true ; Write-output "Component Based Servicing: PackagesPending"}
84 | if (($WMI_Reg.EnumKey($HKLM,"SOFTWARE\Microsoft\ServerManager")).sNames -contains 'CurrentRebootAttempts') {$PendingReboot = $true ; Write-output "ServerManager: CurrentRebootAttempts"}
85 | if (($WMI_Reg.EnumKey($HKLM,"SYSTEM\CurrentControlSet\Services\Netlogon")).sNames -contains 'JoinDomain') {$PendingReboot = $true ; Write-output "Netlogon: JoinDomain"}
86 | #Checking for SCCM namespace
87 | $SCCM_Namespace = Get-WmiObject -Namespace ROOT\CCM\ClientSDK -List -ComputerName $Computer -ErrorAction Ignore
88 | if ($SCCM_Namespace) {
89 | if (([WmiClass]"\\$Computer\ROOT\CCM\ClientSDK:CCM_ClientUtilities").DetermineIfRebootPending().RebootPending -eq $true) {$PendingReboot = $true ; Write-output "SCCM: RebootPending"}
90 | }
91 | }
92 | } catch {
93 | Write-Error $_.Exception.Message
94 | } finally {
95 | #Clearing Variables
96 | $null = $WMI_Reg
97 | $null = $SCCM_Namespace
98 | IF ($PendingReboot) { $reboot = $true }
99 | }
100 | }
101 |
102 | END { Return $PendingReboot }
103 | }
104 | #ENDREGION Functions
105 | $scriptversion = "1.1"
106 | Write-Output "Remove-AzureArc.ps1 Version $scriptversion "
107 | $AzureArc = $( (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -ErrorAction SilentlyContinue ).UBR -ge 2031)
108 | IF ( -not $AzureArc)
109 | { Write-Output "Patchlevel is not high enough for Azure Arc - No action required " }
110 | Else {
111 | # Get-WindowsFeature -Name AzureArcSetup
112 | IF ( (get-WindowsFeature -Name AzureArcSetup).InstallState -like "Installed" ) {Write-Warning "AzureArc is Installed - Remove Feature Restart required" ; Uninstall-WindowsFeature -Name AzureArcSetup -Restart:$false -confirm:$false }
113 | ELSE { Write-Output "Windows Arc is not installed"}
114 | IF ( Get-PendingRebootStatus ) {
115 | Write-Warning "Reboot required - Will reboot in 60 sec. Use >Shutdown.exe /a< to abort."
116 | shutdown.exe /t 60 /r /c "Reboot required" /d p:2:4
117 | }
118 | }
--------------------------------------------------------------------------------
/BitLocker/Update-BitLockerRecovery.ps1:
--------------------------------------------------------------------------------
1 |
2 | <#PSScriptInfo
3 |
4 | .VERSION 1.0.1
5 |
6 | .GUID 3c0736ab-4777-4b58-ae0f-80b4e89b64a2
7 |
8 | .AUTHOR Fabian Niesen
9 |
10 | .COMPANYNAME InfrastrukturHelden.de | Fabian Niesen Online Services
11 |
12 | .COPYRIGHT
13 |
14 | .TAGS BitLocker PowerShell Update ActiveDirectory RecoveryKeys
15 |
16 | .LICENSEURI
17 |
18 | .PROJECTURI https://www.infrastrukturhelden.de/microsoft-infrastruktur/active-directory/bitlocker-wiederherstellungs-keys-nachtraglich-im-ad-sichern/
19 |
20 | .ICONURI
21 |
22 | .EXTERNALMODULEDEPENDENCIES
23 |
24 | .REQUIREDSCRIPTS
25 |
26 | .EXTERNALSCRIPTDEPENDENCIES
27 |
28 | .RELEASENOTES
29 |
30 |
31 | #>
32 |
33 |
34 |
35 | <#
36 | .SYNOPSIS
37 | Upload BitLocker recovery information to Active Directory, if they not already exist.
38 |
39 | .DESCRIPTION
40 | Upload BitLocker recovery information to Active Directory, if they not already exist.
41 | WARNING: While the manage-bde Output is localized, this will only work on English and German Windows 10 devices.
42 |
43 | .EXAMPLE
44 | C:\PS> Update-BitLockerRecovery.ps1
45 |
46 | .EXAMPLE
47 | C:\PS> Update-BitLockerRecovery.ps1 -locale "de-DE"
48 |
49 | .PARAMETER locale
50 | Language code of the OS, if not set the script will use "GET-WinSystemLocale" for autodetection
51 |
52 | .PARAMETER procstate
53 | String to determin the protection state based on the localized output of "manage-bde -status"
54 |
55 | .PARAMETER procstatepat
56 | Pattern to determin the if the protection state based on the localized output of "manage-bde -status" is enabled
57 |
58 | .PARAMETER adcheck
59 | Check Active Directory and shows the key. Require Active Directory PowerShell module installed and Domain Admin permissions
60 |
61 | .NOTES
62 | Author : Fabian Niesen (infrastrukturhelden.de)
63 | Filename : Update-BitLockerRecovery.ps1
64 | Requires : PowerShell Version 3.0
65 | License : The MIT License (MIT)
66 | Copyright (c) 2022-2025 Fabian Niesen
67 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
68 | files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
69 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
70 | furnished to do so, subject to the following conditions:
71 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
72 | The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties
73 | of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be
74 | liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in
75 | connection with the software or the use or other dealings in the Software.
76 | Disclaimer : This script is provided "as is" without warranty. Use at your own risk.
77 | The author assumes no responsibility for any damage or data loss caused by this script.
78 | Test thoroughly in a controlled environment before deploying to production.
79 | Version : 1.2
80 | History : 1.2 FN 03.12.2025 Changed License to MIT, housekeeping Header
81 | 1.1 FN 09.12.2021 Change Locale setting after feedback from Jonas. Thanks
82 | 1.0 FN 01/22/2021 initial version
83 |
84 | .LINK
85 | https://www.infrastrukturhelden.de/microsoft-infrastruktur/active-directory/bitlocker-wiederherstellungs-keys-nachtraglich-im-ad-sichern/
86 | #>
87 | Param(
88 | [Parameter(Mandatory=$false, Position=0, ValueFromPipeline=$False)]
89 | [String]$procstate="",
90 | [Parameter(Mandatory=$false, Position=1, ValueFromPipeline=$False)]
91 | [String]$procstatepat="",
92 | [Parameter(Mandatory=$false, Position=2, ValueFromPipeline=$false)]
93 | [string]$locale = $((Get-UICulture).Name),
94 | [switch]$adcheck
95 | )
96 | $scriptversion = "1.2"
97 | Write-Output "Update-BitLockerRecovery.ps1 Version $scriptversion "
98 | $ErrorActionPreference = "Stop"
99 | If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
100 | {
101 | $arguments = "& '" + $myinvocation.mycommand.definition + "'"
102 | Start-Process powershell -Verb runAs -ArgumentList $arguments
103 | Break
104 | }
105 | switch($locale){
106 | "de-DE" {$procstate = "Schutzstatus" ; $procstatepat = "*Der Schutz ist aktiviert*" ; Write-Verbose "Locale set to de-DE"}
107 | "en-EN" {$procstate = "Protection" ; $procstatepat = "*Protection On*" ; Write-Verbose "Locale set to en-EN"}
108 | Default {IF ($procstate -eq "" -or $procstatepat-eq "") { Write-Error -Message "Locale not prefinied in script! Please use parameter procstate and procstatepat. Please execute >Get-Help .\Update-BitLockerRecovery.ps1 -Detailed<" -Category NotImplemented }}
109 | }
110 |
111 | Try { New-Item -Path HKLM:\SOFTWARE\Policies\Microsoft -Name FVE } Catch {Write-Warning "Registry path already exists"}
112 | Set-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\FVE -Name OSRecovery -Value 1 -Type DWord -Force;
113 | Set-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\FVE -Name OSManageDRA -Value 1 -Type DWord -Force;
114 | Set-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\FVE -Name OSRequireActiveDirectoryBackup -Value 0 -Type DWord -Force;
115 | Set-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\FVE -Name OSActiveDirectoryInfoToStore -Value 1 -Type DWord -Force;
116 | Set-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\FVE -Name OSActiveDirectoryBackup -Value 1 -Type DWord -Force;
117 | Set-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\FVE -Name OSHideRecoveryPage -Value 0 -Type DWord -Force
118 | Get-PSDrive -PSProvider FileSystem | Where-Object { !($_.DisplayRoot -ilike "\\*") } | ForEach-Object {
119 | $root = $_.Root # Fetch the drive letter or mount point
120 | if ($root -ilike "*\") { $root = $root.substring(0, $root.length - 1) } # Remove trailing backslash
121 | [string] $status = (manage-bde -status $root) | Select-String -Pattern $procstate
122 | Write-verbose "Status: $status"
123 | if ($status -ilike $procstatepat) {
124 | [string] $id = (manage-bde -protectors -get $root -Type recoverypassword) | Select-String -Pattern ID
125 | $id = $id.Replace("ID: ", "").Trim()
126 | Write-verbose "ID: $id"
127 | manage-bde -protectors -adbackup $root -id $id
128 | Start-Sleep -Seconds 10
129 | }
130 | }
131 | Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\FVE -Name OSRecovery -Force;
132 | Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\FVE -Name OSManageDRA -Force;
133 | Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\FVE -Name OSRequireActiveDirectoryBackup -Force;
134 | Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\FVE -Name OSActiveDirectoryInfoToStore -Force;
135 | Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\FVE -Name OSActiveDirectoryBackup -Force;
136 | Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\FVE -Name OSHideRecoveryPage -Force
137 | Write-Verbose "Setting back GPO Settings"
138 | GPupdate.exe /Target:Computer /Force
139 | if ($adcheck -eq $false ) {
140 | try
141 | {
142 | Import-Module ActiveDirectory
143 | }
144 | catch
145 | {
146 | Write-Warning "ActiveDirectory Module ist missing. Please install for local check"
147 | break
148 | }
149 | Write-Output "Wait 30 sec to process and AD sync"
150 | Start-Sleep -Seconds 30
151 | $recoveryPass = Get-ADObject -Filter {objectclass -eq 'msFVE-RecoveryInformation'} -SearchBase $($env:COMPUTERNAME).DistinguishedName -Properties 'msFVE-RecoveryPassword' | Where-Object {$_.DistinguishedName -like "*$id*"}
152 | Write-Output "Stored Recovery Password in AD: $recoveryPass "
153 | }
154 |
155 |
--------------------------------------------------------------------------------
/ActiveDirectory/Locate-ADLockout.ps1:
--------------------------------------------------------------------------------
1 | #requires -version 2.0
2 | #requires -modules activedirectory
3 |
4 |
5 | <#
6 | .SYNOPSIS
7 | Locate user Lockouts in Active Directory
8 | .DESCRIPTION
9 | Query all DC and Locate user Lockouts in Active Directory within the last 24h. As default the result is shown as Grid-View, but CSV Export is possible.
10 | A lunchtime project...
11 | .EXAMPLE
12 | .\LocateADLockout-v2.ps1 -filter "bn" -CSVOUT $true -Gridview $false -CSVpath
13 | .INPUTS
14 | -RunAs For future use
15 | -filter only DC's with this pattern in the Hostname
16 | -Gridview Output as GridView
17 | -CSVOUT Export as CSV
18 | -CSVpath Exportpath for CSV
19 | .OUTPUTS
20 | Keine.
21 | .NOTES
22 | Author : Fabian Niesen
23 | Filename : Locate-ADLockout.ps1
24 | Requires : PowerShell Version 2.0
25 |
26 | Version : 1.0
27 | History : 1.0
28 |
29 | .LINK
30 | https://www.infrastrukturhelden.de
31 | #>
32 |
33 | Param(
34 | [Parameter(Mandatory=$false, ValueFromPipeline=$True)]
35 | [String]$RunAs = $false,
36 | [Parameter(Mandatory=$false, ValueFromPipeline=$True)]
37 | [String]$filter ="*",
38 | [Parameter(Mandatory=$false, ValueFromPipeline=$True)]
39 | [String]$Gridview =$true,
40 | [Parameter(Mandatory=$false, ValueFromPipeline=$True)]
41 | [String]$CSVOUT = $false,
42 | [Parameter(Mandatory=$false, ValueFromPipeline=$True)]
43 | [String]$CSVpath = "changeme"
44 | )
45 |
46 | $LogOuts = @()
47 |
48 |
49 | #@{label=''}, @{label=''},@{label=''}, @{label=''}, @{label=''}
50 | $DCs = Get-ADDomainController -Filter { HostName -like "$filter" }
51 | ForEach ($DC in $DCs)
52 | {
53 | Write-Output "Starte Remote PowerShell Session zu: "$DC.HostName
54 | $temp = Invoke-Command -ComputerName $DC.HostName -ScriptBlock { Get-EventLog -LogName "Security" -After (Get-Date).AddDays(-1) | Where-Object { $_.EventID -match '4740' -or $_.EventID -match '644'} }
55 | ForEach ($t in $temp)
56 | {
57 | $Log = New-Object -TypeName psobject
58 | $Log | Add-Member -MemberType NoteProperty -Name TimeGenerated -Value $t.TimeGenerated
59 | $Log | Add-Member -MemberType NoteProperty -Name DC -Value $t.ReplacementStrings[4]
60 | $Log | Add-Member -MemberType NoteProperty -Name Benutzer -Value $t.ReplacementStrings[0]
61 | $Log | Add-Member -MemberType NoteProperty -Name Quelle -Value $t.ReplacementStrings[1]
62 | $Log | Add-Member -MemberType NoteProperty -Name LoginID -Value $t.ReplacementStrings[6]
63 | $LogOuts += $Log
64 | }
65 | }
66 |
67 | IF ($Gridview -eq $true) { $LogOuts | Out-GridView -Title "Account Lockouts" }
68 | IF ($CSVOUT -eq $true)
69 | {
70 | IF ($CSVpath -like "changeme")
71 | {
72 | Write-Verbose "No Path found"
73 | $CSVpath = Read-Host -Prompt "Bitte geben Sie einen Dateinamen inklusive Pfad an"
74 | }
75 | $LogOuts | Export-Csv -Path $CSVpath -Delimiter ";" -NoTypeInformation
76 | }
77 |
78 | <# If I have to much time left...
79 | ### Runas Auswertung der Aufgabenplanung pro User und System
80 | IF ($RunAs -eq $true)
81 | {
82 | $SchedService.Connect($ComputerName)
83 | $TaskFolder = $SchedService.GetFolder("")
84 | $RootTasks = $TaskFolder.GetTasks("")
85 | Foreach ($Task in $RootTasks)
86 | {
87 | Switch ($Task.State)
88 | {
89 | 0 {$Status = "Unknown"}
90 | 1 {$Status = "Disabled"}
91 | 3 {$Status = "Ready"}
92 | 4 {$Status = "Running"}
93 | }#End Switch ($Task.State)
94 | $Xml = $Task.Xml
95 | #The code below parses the Xml String Data for the "RunAs User" that is returned from the Schedule.Service COM Object
96 | [String]$RunUser = $Xml[(($Xml.LastIndexOf(""))+8)..(($Xml.LastIndexOf(""))-1)]
97 | $RunUser = $RunUser.Replace(" ","").ToUpper()
98 | $Result = New-Object PSObject -Property @{
99 | ServerName=$ComputerName
100 | TaskName=$Task.Name
101 | RunAs=$RunUser
102 | LastRunTime=$Task.LastRunTime
103 | NextRunTime=$Task.NextRunTime
104 | }#End $Result = New-Object
105 | $Result = $Result | Select-Object Servername, TaskName, RunAs, LastRunTime, NextRunTime
106 |
107 | #>
108 |
109 | # SIG # Begin signature block
110 | # MIINhAYJKoZIhvcNAQcCoIINdTCCDXECAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
111 | # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
112 | # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUY5VekahfDkMzynRQdVSHw6kI
113 | # pG2gggrDMIIE1zCCA7+gAwIBAgIQQqUulpP/t+xNJTeKzXz8XzANBgkqhkiG9w0B
114 | # AQsFADB1MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEpMCcG
115 | # A1UECxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIzAhBgNVBAMT
116 | # GlN0YXJ0Q29tIENsYXNzIDMgT2JqZWN0IENBMB4XDTE2MDcyMDA4MjM0MFoXDTE5
117 | # MDcyMDA4MjM0MFowZDELMAkGA1UEBhMCREUxHDAaBgNVBAgME05vcmRyaGVpbi1X
118 | # ZXN0ZmFsZW4xDTALBgNVBAcMBEJvbm4xEzARBgNVBAoMCnN0ZWVwIEdtYkgxEzAR
119 | # BgNVBAMMCnN0ZWVwIEdtYkgwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
120 | # AQDEym9W07bauIxBdWBD29HJRWbPEZXE7y/slfD1z2Ldf5dNcbhBN++AcFmmitfD
121 | # 9wC4qa6Masw2bcILUqyxY0kTb1zUpV5RPJ389e2mzvsgaQyIsqB+tIUHxdhiyRzc
122 | # i9yFmNybCErwEzNueU37BAxpc21OYn44IExSfP26qsKlEi1KxukHv+pWZbLfZpCt
123 | # T/WE+lZxNTxzjDezk9c0m5wQ+HSShcFUwViBf/h2Ov+05ZhH7j1RjvUSmLSyx0cs
124 | # JL8jaMszouYlRPHnbghD3UD500TjlkT+sstf6JqInGyNYcfa0bsFwbuoKz3SndH1
125 | # RGQ/b4riT5GW0wOljsRtpglBAgMBAAGjggFyMIIBbjAOBgNVHQ8BAf8EBAMCB4Aw
126 | # EwYDVR0lBAwwCgYIKwYBBQUHAwMwCQYDVR0TBAIwADAdBgNVHQ4EFgQUEPS1SOLL
127 | # CkfWuYxHbJz2dHucaNowbQYIKwYBBQUHAQEEYTBfMCQGCCsGAQUFBzABhhhodHRw
128 | # Oi8vb2NzcC5zdGFydHNzbC5jb20wNwYIKwYBBQUHMAKGK2h0dHA6Ly9haWEuc3Rh
129 | # cnRzc2wuY29tL2NlcnRzL3NjYS5jb2RlMy5jcnQwNgYDVR0fBC8wLTAroCmgJ4Yl
130 | # aHR0cDovL2NybC5zdGFydHNzbC5jb20vc2NhLWNvZGUzLmNybDAjBgNVHRIEHDAa
131 | # hhhodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS8wUQYDVR0gBEowSDAIBgZngQwBBAEw
132 | # PAYLKwYBBAGBtTcBAgUwLTArBggrBgEFBQcCARYfaHR0cHM6Ly93d3cuc3RhcnRz
133 | # c2wuY29tL3BvbGljeTANBgkqhkiG9w0BAQsFAAOCAQEAAmEyPAwytipNaWO1N/gf
134 | # c/dMMbf4nKGaIIYSTaguZwdgVwbWEegJ7b51i8kB1+nI3qg+Ez89kmT/Ano4Ot+V
135 | # 7IOx8Hvpfqy1eXKOl2oHVXqEzoZJV/nNf+TFJRk5PKORS8lJIEss9slS79bw4ejI
136 | # LaowcfgHLwmP9yeL3M860edWB+yL00VOVUnYM/Jb2SkCvd1buLUVUluMz1tZdh+s
137 | # B/sGcf2I0sxS8mCbPFuIGJ2LBq859W8MDM4BO1i4tQnLKi5i/VlbVelUtaMTbndS
138 | # WbRn3828k5QnajErzR2C2cAI6Lya8TsKTKKz1I2etM7gPy16II/ygR5q6KoON9n1
139 | # mjCCBeQwggPMoAMCAQICEHgiQ6FT3ygKH/rhXNAoTIYwDQYJKoZIhvcNAQELBQAw
140 | # fTELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsT
141 | # IlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxKTAnBgNVBAMTIFN0
142 | # YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE1MTIxNjAxMDAwNVoX
143 | # DTMwMTIxNjAxMDAwNVowdTELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29t
144 | # IEx0ZC4xKTAnBgNVBAsTIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
145 | # MSMwIQYDVQQDExpTdGFydENvbSBDbGFzcyAzIE9iamVjdCBDQTCCASIwDQYJKoZI
146 | # hvcNAQEBBQADggEPADCCAQoCggEBANhsJTYUZFx5zWGYAp8FlVG8yEBmyldXMpNl
147 | # oFW7wnrfr/7lVSgyZ+ZjL8LvZcDB5nftTaSlvd5MCOJW9WlMICRksLS/2vo5b/Bs
148 | # OjIs5A9j8FSt0far4mtE0dlu5mQ3+6hbn2tgjW+m6aksqDymsAIAAW/NFKCsyrDl
149 | # qNOaujXkfmdpbe0keZqKfDDw7DoHZygP9e6KaDn0pcuheiYNa+T+cqlrV8Tw3sZm
150 | # zPyxv/itSCiR3G+yo9LKDZwVFfRj/tpAJhFAodHEw9Swna2FRYlpA1TZg93QSEDe
151 | # u6HjTR9AJPHA4I4SRhsIL5LuGWVhuxT1hX2pLmKSL2mPACV3etcCAwEAAaOCAWYw
152 | # ggFiMA4GA1UdDwEB/wQEAwIBBjAfBgNVHSUEGDAWBggrBgEFBQcDAwYKKwYBBAGC
153 | # Nz0BATASBgNVHRMBAf8ECDAGAQH/AgEAMDIGA1UdHwQrMCkwJ6AloCOGIWh0dHA6
154 | # Ly9jcmwuc3RhcnRzc2wuY29tL3Nmc2NhLmNybDBmBggrBgEFBQcBAQRaMFgwJAYI
155 | # KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLnN0YXJ0c3NsLmNvbTAwBggrBgEFBQcwAoYk
156 | # aHR0cDovL2FpYS5zdGFydHNzbC5jb20vY2VydHMvY2EuY3J0MB0GA1UdDgQWBBRm
157 | # ep7NnHOGammgrvqMuxiPCOzVBDAfBgNVHSMEGDAWgBROC+8apEBbpRdphzDKNGhD
158 | # 0EGu8jA/BgNVHSAEODA2MDQGBFUdIAAwLDAqBggrBgEFBQcCARYeaHR0cDovL3d3
159 | # dy5zdGFydHNzbC5jb20vcG9saWN5MA0GCSqGSIb3DQEBCwUAA4ICAQALH3fwpLbm
160 | # kgX1R/F0c6VgGrehmK66gJnxuJbU+iPpymMFgggAr5TMITlT1VGYaAHA4PZTvlgR
161 | # mL3ZrhHnn+/TI03MZyt4XluVm0qju0w0R+EpeUZHycXTKK51G8Jjvfn9u1GnsgKT
162 | # QFNeep1p+f40LvQai2wLQgCJ4ScvqIUK5+2FJvS4yNOugZejNyw45duXUyWukBah
163 | # G2fQFcW6yZuvjHHh7qfAi2Dyv1w6FeJeHNP/tPhYdQK6bRKDM//EDFyXY/+xEWaB
164 | # REDDI8D2HJVvJ8p0AIZQatPNBiF7AdiPSZVBYwhXBr9n7NwOrFkqARvHmecrdQ1h
165 | # IwSMUtIuvHtRUJKin6J4dJWDnvO3llnKrhHYnpu4SgzC6Dk2KGbppnbaxP8x4rJd
166 | # jWkkiltYfYuv0oy8UjEPHZAvlqhGmnc2q5kvVc0NtXgD5IipE8xybXrI9nd5uErP
167 | # hR4eSvguRy5aNusuF//bdcB9lGhMM3V2QyLRgABXh34TwfBVSvLrnwThqC06t66n
168 | # iXyxqA/98iad8PdAHfSkyRBMMNxk0LVSETfJ/FtVJr6JvWPfQgRxek+L8s6sw/bb
169 | # 4Jr6LnCCQjaChoDFrn0CevRgDsodMJbbFPToTJk8sgOOK1D3mWOAhLL1G765DD80
170 | # ytzX/aOOXA5wfpQTTzIb/6SPXHX1nKRYyTGCAiswggInAgEBMIGJMHUxCzAJBgNV
171 | # BAYTAklMMRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSkwJwYDVQQLEyBTdGFydENv
172 | # bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEjMCEGA1UEAxMaU3RhcnRDb20gQ2xh
173 | # c3MgMyBPYmplY3QgQ0ECEEKlLpaT/7fsTSU3is18/F8wCQYFKw4DAhoFAKB4MBgG
174 | # CisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcC
175 | # AQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYE
176 | # FP8IdNLO8hTUzYNJpRoTG5P7aAtJMA0GCSqGSIb3DQEBAQUABIIBAGtwmWDP5UfK
177 | # KVx9Gz7hb8iWerlkk87ADhtIyFJs8LtBM5eSHCTmzTn3BEv5TsAIqCb692w70i1d
178 | # c812ehjpZbR6hvumMtBG+YgggqbxuaMzrppBJbMKZ/L3dWQY4LNpvEU+O+Vv0fhc
179 | # +abVe7sJXuUjGzgQYpiMkWyWUVQvh/gOJo4ytCvwfdP1D6PUPabvVsWd0Xzzh37U
180 | # 4jGaYTDg45DoO/Wa812j/+abYwqCAZuwkN0P++n+QTBBZQR47d6vFwTymiGEPiLB
181 | # hAraXkOw7e/BCmORydk3asLmHc0OVJmKqiedKpuSgy8wfScVH5nz3Y1ugSeHTuQ9
182 | # v8QIjIQpH/0=
183 | # SIG # End signature block
184 |
--------------------------------------------------------------------------------
/WSUS/start-WsusServerSync.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | $WsusServer = ([system.net.dns]::GetHostByName('localhost')).hostname,
3 | [switch]$Recursive,
4 | [bool]$TrialRun = $false,
5 | [int]$SleepTime = 60,
6 | [string]$SmtpServer = "email.server.local",
7 | [string]$From = "Wsus@domain.local",
8 | [string]$To = "admin@domain.local",
9 | [string]$Subject = "WSUS Server Synchronization.",
10 | [switch]$EmailLog
11 | )
12 | Begin
13 | { $script:CurrentErrorActionPreference = $ErrorActionPreference
14 | $script:Output = @()
15 | $script:ProcessedServers = @()
16 | $WsusAssembly = [reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")
17 | If($WsusAssembly -eq $Null)
18 | { throw "Loading Microsoft.UpdateServices.Administration failed. Are you running this on a machine with the WSUS 3.0 SP2 Administration Console installed? http://technet.microsoft.com/en-us/library/dd939875(v=ws.10).aspx"}
19 |
20 | $ErrorActionPreference = "SilentlyContinue"
21 | If($EmailLog)
22 | { If($Recursive)
23 | { $Table = @{Name="Parent Wsus Server";expression={$_.ParentWsusServer}},@{Name="Wsus Server";expression={$_.WsusServer}},@{Name="Port Number";expression={$_.PortNumber}},@{Name="Using SSL";expression={$_.UsingSSL}},@{Name="Version";expression={$_.Version}},@{Name="Start";expression={$_.Start}},@{Name="Finish";expression={$_.Finish}}
24 | }
25 | Else
26 | { $Table = @{Name="Wsus Server";expression={$_.WsusServer}},@{Name="Port Number";expression={$_.PortNumber}},@{Name="Using SSL";expression={$_.UsingSSL}},@{Name="Version";expression={$_.Version}},@{Name="Start";expression={$_.Start}},@{Name="Finish";expression={$_.Finish}}
27 | }
28 | If($TrialRun -eq $False)
29 | { $Table += @{Name="Categories";expression={$_.Categories}},@{Name="Updates";expression={$_.Updates}},@{Name="Approvals";expression={$_.Approvals}},@{Name="LastSyncResult";expression={$_.LastSyncResult}}
30 | }
31 | $Style = ""
35 | Function SendEmailStatus($From, $To, $Subject, $SmtpServer, $BodyAsHtml, $Body)
36 | { $SmtpMessage = New-Object System.Net.Mail.MailMessage $From, $To, $Subject, $Body
37 | $SmtpMessage.IsBodyHTML = $BodyAsHtml
38 | $SmtpClient = New-Object System.Net.Mail.SmtpClient $SmtpServer
39 | $SmtpClient.Send($SmtpMessage)
40 | If($? -eq $False){Write-Warning "$($Error[0].Exception.Message) | $($Error[0].Exception.GetBaseException().Message)"}
41 | $SmtpMessage.Dispose()
42 | rv SmtpClient
43 | rv SmtpMessage
44 | }
45 | }
46 |
47 | function Get-HKLMValue
48 | { Param(
49 | [string]$computername=".",
50 | [string]$key = "SOFTWARE\Microsoft\Update Services\Server\Setup",
51 | [string]$value,
52 | [switch]$REG_SZ,
53 | [switch]$REG_DWORD
54 | )
55 | $HKLM = 2147483650
56 | $reg = [wmiclass]"\\$computername\root\default:StdRegprov"
57 | If($REG_SZ)
58 | { $Result = $reg.GetStringValue($HKLM,$key,$value)
59 | If($Result.ReturnValue -eq 0){$Result.sValue}
60 | }
61 | If($REG_DWORD)
62 | { $Result = $reg.GetDwordValue($HKLM,$key,$value)
63 | If($Result.ReturnValue -eq 0){$Result.uValue}
64 | }
65 | }
66 |
67 | function Start-Pause
68 | { Param(
69 | [int]$SleepTime = 10,
70 | [int]$ID = 1,
71 | [int]$ParentID,
72 | [string]$Activity = "Just taking a quick breather after all that activity..."
73 | )
74 | for($x = 1 ; $x -le $SleepTime; $x++)
75 | { If(!$ParentID)
76 | { Write-progress -Activity $Activity -Status "Seconds Remaining: $($SleepTime-$x)" -PercentComplete ($x/$SleepTime*100) -ID $ID}
77 | Else
78 | { Write-progress -Activity $Activity -Status "Seconds Remaining: $($SleepTime-$x)" -PercentComplete ($x/$SleepTime*100) -ID $ID -ParentId $ParentID}
79 | Sleep 1
80 | }
81 | Write-progress -Activity $Activity -Status "Done sleeping..." -Completed -ID $ID
82 | }
83 |
84 | Function Sync-WsusServer
85 | { Param(
86 | $WsusServer,
87 | $ParentWsusServer
88 | )
89 | Write-Progress -Activity "Processing server: $WsusServer" -Status "Started at $((get-date).DateTime)" -ID 2 -ParentID 1
90 | Write-Progress -Activity "Retrieving PortNumber value from the registry via StdRegprov ..." -Status "Started at $((get-date).DateTime)" -ID 3 -ParentID 2
91 | $PortNumber = Get-HKLMValue -Computername $WsusServer -value PortNumber -REG_DWORD
92 | Write-Progress -Activity "Retrieving UsingSSL value from the registry via StdRegprov ..." -Status "Started at $((get-date).DateTime)" -ID 3 -ParentID 2
93 | $UsingSSL = If((Get-HKLMValue -Computername $WsusServer -value UsingSSL -REG_DWORD) -eq 1){$True}Else{$False}
94 | If($UsingSSL)
95 | { Write-Progress -Activity "Retrieving ServerCertificateName value from the registry via StdRegprov ..." -Status "Started at $((get-date).DateTime)" -ID 3 -ParentID 2
96 | $ServerCertificateName = Get-HKLMValue -Computername $WsusServer -value ServerCertificateName -REG_SZ
97 | If($ServerCertificateName){$WsusServer = $ServerCertificateName}
98 | }
99 | If($script:ProcessedServers -Contains $WsusServer)
100 | { Write-Warning "$WsusServer appears to have already been processed. You may have a circular loop in your hierarchy."}
101 | Else
102 | { $script:ProcessedServers += $WsusServer
103 | $Object = New-Object psobject
104 | If($Recursive)
105 | { If(!$ParentWsusServer){$ParentWsusServer = "--"}
106 | $Object | Add-Member NoteProperty ParentWsusServer $ParentWsusServer
107 | }
108 | $Object | Add-Member NoteProperty WsusServer $WsusServer -PassThru | Add-Member NoteProperty PortNumber $PortNumber -PassThru |
109 | Add-Member NoteProperty UsingSSL $UsingSSL -PassThru | Add-Member NoteProperty Version "" -PassThru |
110 | Add-Member NoteProperty Start (get-date).DateTime -PassThru | Add-Member NoteProperty Finish ""
111 | If($TrialRun -eq $False)
112 | { $Object | Add-Member NoteProperty Categories "--" -PassThru |
113 | Add-Member NoteProperty Updates "--" -PassThru |
114 | Add-Member NoteProperty Approvals "--" -PassThru |
115 | Add-Member NoteProperty LastSyncResult ""
116 | }
117 | Write-Progress -Activity "Connecting to UpdateServices AdminProxy..." -Status "Started at $((get-date).DateTime)" -ID 3 -ParentID 2
118 | $WsusServerAdminProxy = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer($WsusServer,$UsingSSL,$PortNumber)
119 | If ($? -eq $False)
120 | { $Object.Version = $Error[0]
121 | Write-Warning "Failed to connect to $WsusServer $($Error[0])"
122 | $Object.Finish = (get-date).DateTime
123 | $Object
124 | If($EmailLog){$script:Output += $Object}
125 | }
126 | Else
127 | { $Object.Version = $WsusServerAdminProxy.Version
128 | If($TrialRun -eq $False)
129 | { Write-Progress -Activity "Connecting to the Subscription..." -Status "Started at $((get-date).DateTime)" -ID 3 -ParentID 2
130 | $Subscription = $WsusServerAdminProxy.GetSubscription();
131 | Write-Progress -Activity "Calling StartSynchronization on $WsusServer" -Status "Started at $((get-date).DateTime)" -ID 3 -ParentID 2
132 | $Subscription.StartSynchronization()
133 | $SynchronizationProgress = $Subscription.GetSynchronizationProgress()
134 | While ($SynchronizationProgress.Phase.ToString() -eq "NotProcessing")
135 | { Start-Sleep -Milliseconds 100
136 | $SynchronizationProgress = $Subscription.GetSynchronizationProgress()
137 | }
138 | While ($SynchronizationProgress.Phase.ToString() -ne "NotProcessing")
139 | { If($SynchronizationProgress.Phase.ToString() -eq "Categories")
140 | {$Object.Categories = $SynchronizationProgress.TotalItems}
141 | If($SynchronizationProgress.Phase.ToString() -eq "Updates")
142 | { $Object.Updates = $SynchronizationProgress.TotalItems}
143 | If($SynchronizationProgress.Phase.ToString() -eq "Approvals")
144 | {$Object.Approvals = $SynchronizationProgress.TotalItems}
145 | Write-Progress -Activity "Synchronization Phase: $($SynchronizationProgress.Phase.ToString())" -Status "$($SynchronizationProgress.ProcessedItems) of $($SynchronizationProgress.TotalItems) items done..." -PercentComplete ($SynchronizationProgress.ProcessedItems*100/($SynchronizationProgress.TotalItems)) -ID 4 -ParentId 3
146 | $SynchronizationProgress = $Subscription.GetSynchronizationProgress()
147 | }
148 | $Object.LastSyncResult = $Subscription.GetLastSynchronizationInfo().Result
149 | Write-Progress -Activity "Synchronization Phase: $($SynchronizationProgress.Phase.ToString())" -Status "Complete." -ID 4 -ParentId 3 -Completed
150 | }
151 | $Object.Finish = (get-date).DateTime
152 | $Object
153 | If($EmailLog){$script:Output += $Object}
154 | If($Recursive -And $TrialRun -eq $False){Start-Pause -Activity "Processed $($script:ProcessedServers.Count) server(s). The script is pausing for $SleepTime seconds starting at $((get-date).DateTime)." -SleepTime $SleepTime -ID 3 -ParentID 2}
155 | If($Recursive)
156 | { Write-Progress -Activity "Retrieving Downstream Servers on $WsusServer..." -Status "Started at $((get-date).DateTime)" -ID 3 -ParentID 2
157 | $WsusDownstreamServers = $WsusServerAdminProxy.GetDownstreamServers()
158 | If($WsusDownstreamServers){$WsusDownstreamServers | %{Sync-WsusServer -WsusServer $_.FullDomainName -ParentWsusServer $WsusServer}}
159 | }
160 | }
161 | }
162 | }
163 | Write-Progress -Activity "WSUS Server Synchronization." -Status "Started at $((get-date).DateTime)" -ID 1
164 | }
165 | Process
166 | { If($WsusServer)
167 | { ForEach($Server in $WsusServer){Sync-WsusServer $Server}
168 | }
169 | Else
170 | { Sync-WsusServer $_
171 | }
172 | }
173 | End
174 | { If($EmailLog){SendEmailStatus -From $From -To $To -Subject $Subject -SmtpServer $SmtpServer -BodyAsHtml $True -Body ($Output | Select $Table | ConvertTo-HTML -head $Style)}
175 | $ErrorActionPreference = $script:CurrentErrorActionPreference
176 | }
--------------------------------------------------------------------------------
/Intune/get-AutopilotLogs.ps1:
--------------------------------------------------------------------------------
1 | #Requires -RunAsAdministrator
2 | <#
3 | .SYNOPSIS
4 | Gather Informations & Logs for Autopilot Pre-Provisioning process.
5 |
6 | .DESCRIPTION
7 | Gather Informations & Logs for Autopilot Pre-Provisioning process. It creates a folder in the locaion where it was started from, usually a USB Thumdrive.
8 |
9 | .EXAMPLE
10 | C:\PS> get-AutopilotLogs.ps1
11 |
12 | .NOTES
13 | Author : Fabian Niesen (www.fabian-niesen.de)
14 | Filename : get-AutopilotLogs.ps1
15 | Requires : PowerShell Version 4.0
16 | Version : 1.0.2
17 | History : 1.0.2 FN 26.08.2022 Add ToDo list, changed LogName
18 | 1.0.1 FN 25.08.2022 Buxfixes
19 | 1.0.0 FN 21.08.2022 initial version
20 |
21 | .ToDo
22 | - Integrate Networkchecks
23 | - Integrate TPM check
24 | - Gather MDM Policies from Registry
25 |
26 | .LINK
27 | https://github.com/InfrastructureHeroes/Scipts/
28 |
29 | .COPYRIGHT
30 | Copyright (c) Fabian Niesen if not stated otherwise. All rights reserved. Licensed under the MIT license.
31 |
32 | #>
33 | $ErrorActionPreference = "SilentlyContinue"
34 | $script:BuildVer = "1.0.2"
35 | $script:ProgramFiles = $env:ProgramFiles
36 | $script:ParentFolder = $PSScriptRoot | Split-Path -Parent
37 | $script:ScriptName = $myInvocation.MyCommand.Name
38 | $script:ScriptName = $scriptName.Substring(0, $scriptName.Length - 4)
39 | $serial = $(Get-WmiObject Win32_bios).Serialnumber
40 | $Device = Get-CimInstance -ClassName Win32_ComputerSystem
41 | $LogName = (Get-Date -UFormat "%Y%m%d-%H%M")+ "_" + $serial
42 | $Logpath = $PSScriptRoot + "\" + $LogName
43 | $LogFile = $Logpath +"\" + $script:ScriptName + ".log"
44 | $ntpserver = "ptbtime1.ptb.de,ptbtime2.ptb.de,time.windows.com,time.nist.gov"
45 | ####################################################
46 | #region Logfiles
47 | <#
48 | .COPYRIGHT for this region
49 | Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
50 | See LICENSE in the project https://github.com/gregnottage/IntuneScripts for license information.
51 |
52 | .Notes
53 | Removed EventLog Handling and smaller changes by Fabian Niesen
54 | #>
55 | Function Start-Log {
56 | param (
57 | [string]$FilePath,
58 |
59 | [Parameter(HelpMessage = 'Deletes existing file if used with the -DeleteExistingFile switch')]
60 | [switch]$DeleteExistingFile
61 | )
62 |
63 | Try {
64 | If (!(Test-Path $FilePath)) {
65 | ## Create the log file
66 | New-Item $FilePath -Type File -Force | Out-Null
67 | }
68 |
69 | If ($DeleteExistingFile) {
70 | Remove-Item $FilePath -Force
71 | }
72 |
73 | ## Set the global variable to be used as the FilePath for all subsequent Write-Log
74 | ## calls in this session
75 | $script:ScriptLogFilePath = $FilePath
76 | }
77 | Catch {
78 | Write-Error $_.Exception.Message
79 | }
80 | }
81 |
82 | ####################################################
83 |
84 | Function Write-Log {
85 | #Write-Log -Message 'warning' -LogLevel 2
86 | #Write-Log -Message 'Error' -LogLevel 3
87 | param (
88 | [Parameter(Mandatory = $true)]
89 | [string]$Message,
90 |
91 | [Parameter()]
92 | [ValidateSet(1, 2, 3)]
93 | [int]$LogLevel = 1,
94 |
95 | [Parameter(HelpMessage = 'Outputs message to Event Log,when used with -WriteEventLog')]
96 | [switch]$WriteEventLog
97 | )
98 | Write-Host $Message
99 | $TimeGenerated = "$(Get-Date -Format HH:mm:ss).$((Get-Date).Millisecond)+000"
100 | $Line = '