NTS.Tools.General.psm1
function Start-FolderCleanUp { <# .Description this function can be used to remove folders and its items .Parameter FolderToRemove version of sql reporting services setup .Example # this will remove the folder $SSRSTempFolder and its items Start-CleanUp -FolderToRemove $SSRSTempFolder .NOTES #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $FolderToRemove ) Write-Output "$($env:COMPUTERNAME): removing temp files from $($FolderToRemove)" try { Remove-Item -Path $FolderToRemove -Recurse -Force } catch { throw "error while cleanup - $($PSItem.Exception.Message)" } Write-Output "$($env:COMPUTERNAME): cleanup finished" } function Set-Interface { <# .Description configures the network interface, ip, dns, gateway .Parameter InterfaceObject nic objects .Parameter IPAddress ipaddress .Parameter NetPrefix net prefix, e.g. 24 .Parameter DefaultGateway default gateway in the subnet .Parameter DNSAddresses dns server addresses .Parameter NewName new name of the network adapter .Example # configures the specified network card Set-Interface -InterfaceObject $SFP10G_NICs[0] -IPAddress $CLU1_IPAddress -NetPrefix $NetPrefix -DefaultGateway $CLU_DefaultGateway -DNSAddresses $CLU_DNSAddresses -NewName "Datacenter-1" .NOTES #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] $InterfaceObject, [Parameter(Mandatory = $true)] $IPAddress, [Parameter(Mandatory = $true)] $NetPrefix, [Parameter(Mandatory = $false)] $DefaultGateway, [Parameter(Mandatory = $false)] $DNSAddresses, [Parameter(Mandatory = $false)] $NewName ) try { Write-Output "$($env:COMPUTERNAME): configuring nic with macaddress $($InterfaceObject.MacAddress)" If (($InterfaceObject | Get-NetIPConfiguration).IPv4Address.IPAddress) { $InterfaceObject | Remove-NetIPAddress -AddressFamily "IPv4" -Confirm:$false } If (($InterfaceObject | Get-NetIPConfiguration).Ipv4DefaultGateway) { $InterfaceObject | Remove-NetRoute -AddressFamily "IPv4" -Confirm:$false } Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces\$($InterfaceObject.InterfaceGuid)" -Name EnableDHCP -Value 0 Start-Sleep -Seconds 2 if ($null -ne $DefaultGateway) { $InterfaceObject | New-NetIPAddress -IPAddress $IPAddress -AddressFamily "IPv4" -PrefixLength $NetPrefix -DefaultGateway $DefaultGateway | Out-Null Write-Output "$($env:COMPUTERNAME): interface $($InterfaceObject.InterfaceDescription) has the static ip $($IPAddress) now" } else { $InterfaceObject | New-NetIPAddress -IPAddress $IPAddress -AddressFamily "IPv4" -PrefixLength $NetPrefix | Out-Null Write-Output "$($env:COMPUTERNAME): interface $($InterfaceObject.InterfaceDescription) has the static ip $($IPAddress) now" } if ($null -ne $DNSAddresses) { $InterfaceObject | Set-DnsClientServerAddress -ServerAddresses $DNSAddresses } if ($null -ne $NewName) { $InterfaceObject | Rename-NetAdapter -NewName $NewName Write-Output "$($env:COMPUTERNAME): interface $($InterfaceObject.InterfaceDescription) renamed to $($NewName)" } } catch { throw "error setting $($InterfaceObject.Name): $($PSItem.Exception.Message)" } } function Test-FileLock { <# .Description this function test if a file is in use and returns true if so .Parameter Path file path to the file .Example # this checks if the file is in use Test-FileLock -Path C:\WINDOWS\CCM\Logs\PolicyAgentProvider.log .NOTES https://stackoverflow.com/questions/24992681/powershell-check-if-a-file-is-locked #> [CmdletBinding()] param ( [parameter(Mandatory = $true)] [string] $Path ) $oFile = New-Object System.IO.FileInfo $Path if ((Test-Path -Path $Path) -eq $false) { return $false } try { $oStream = $oFile.Open([System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None) if ($oStream) { $oStream.Close() } $false } catch { # file is locked by a process. return $true } } function Test-RebootPending { ############################################################################### # Check-PendingReboot.ps1 # Andres Bohren / www.icewolf.ch / blog.icewolf.ch / a.bohren@icewolf.ch # Version 1.0 / 03.06.2020 - Initial Version - Andres Bohren # Version 1.1 / 27.04.2022 - Updated Script - Andres Bohren ############################################################################### <# .SYNOPSIS This Script checks diffrent Registry Keys and Values do determine if a Reboot is pending. .DESCRIPTION I found this Table on the Internet and decided to Write a Powershell Script to check if a Reboot is pending. Not all Keys are checked. But feel free to extend the Script. https://adamtheautomator.com/pending-reboot-registry-windows/ KEY VALUE CONDITION HKLM:\SOFTWARE\Microsoft\Updates UpdateExeVolatile Value is anything other than 0 HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager PendingFileRenameOperations value exists HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager PendingFileRenameOperations2 value exists HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired NA key exists HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Services\Pending NA Any GUID subkeys exist HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\PostRebootReporting NA key exists HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce DVDRebootSignal value exists HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending NA key exists HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootInProgress NA key exists HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\PackagesPending NA key exists HKLM:\SOFTWARE\Microsoft\ServerManager\CurrentRebootAttempts NA key exists HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon JoinDomain value exists HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon AvoidSpnSet value exists HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName ComputerName Value ComputerName in HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName is different .EXAMPLE ./Check-PendingReboot.ps1 #> function Test-RegistryValue { param ( [parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$Path, [parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()]$Value ) try { Get-ItemProperty -Path $Path -Name $Value -EA Stop return $true } catch { return $false } } [bool]$PendingReboot = $false #Check for Keys If ((Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired") -eq $true) { # Write-Host "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired" $PendingReboot = $true } If ((Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\PostRebootReporting") -eq $true) { # Write-Host "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\PostRebootReporting" $PendingReboot = $true } If ((Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired") -eq $true) { # Write-Host "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired" $PendingReboot = $true } If ((Test-Path -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending") -eq $true) { # Write-Host "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending" $PendingReboot = $true } If ((Test-Path -Path "HKLM:\SOFTWARE\Microsoft\ServerManager\CurrentRebootAttempts") -eq $true) { # Write-Host "HKLM:\SOFTWARE\Microsoft\ServerManager\CurrentRebootAttempts" $PendingReboot = $true } #Check for Values If ((Test-RegistryValue -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing" -Value "RebootInProgress") -eq $true) { # Write-Host "HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing > RebootInProgress" $PendingReboot = $true } If ((Test-RegistryValue -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing" -Value "PackagesPending") -eq $true) { # Write-Host "HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing > PackagesPending" $PendingReboot = $true } If ((Test-RegistryValue -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Value "PendingFileRenameOperations") -eq $true) { # Write-Host "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager > PendingFileRenameOperations" $PendingReboot = $true } If ((Test-RegistryValue -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Value "PendingFileRenameOperations2") -eq $true) { # Write-Host "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager > PendingFileRenameOperations2" $PendingReboot = $true } If ((Test-RegistryValue -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" -Value "DVDRebootSignal") -eq $true) { # Write-Host "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce > DVDRebootSignal" $PendingReboot = $true } If ((Test-RegistryValue -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon" -Value "JoinDomain") -eq $true) { # Write-Host "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon > JoinDomain" $PendingReboot = $true } If ((Test-RegistryValue -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon" -Value "AvoidSpnSet") -eq $true) { # Write-Host "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon > AvoidSpnSet" $PendingReboot = $true } return $PendingReboot } function Start-FileDownload { <# .Description this function can be used to download files, but also checks if the destination has already the file .Parameter DownloadURL url of the source .Parameter FileOutPath path where the file should be saved, with extension .Parameter MaxAgeOfFile maximum file modification date .Example # downloads the file Start-FileDownload -DownloadURL "https://www.microsoft.com/en-us/download/confirmation.aspx?id=104131" -FileOutPath "$($Outpath)\Exchange-$($Version).iso" .NOTES #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $DownloadURL, [Parameter(Mandatory = $true)] [string] $FileOutPath, [Parameter(Mandatory = $false)] [datetime] $MaxAgeOfFile = (Get-Date).AddHours(-2) ) # verify folder try { $FileName = $FileOutPath.Split("\")[-1] $FolderName = $FileOutPath.replace($FileName, "") if ((Test-Path -Path $FolderName) -eq $false) { New-Item -Path $FolderName -ItemType Directory -Force | Out-Null } } catch { throw "error creating dest folder - $($PSItem.Exception.Message)" } # download try { if ((Test-Path -Path $FileOutPath) -eq $true) { if ((Get-Item $FileOutPath).LastWriteTime -gt $MaxAgeOfFile) { Write-Output "$($env:COMPUTERNAME): found $($FileOutPath), will use it" } else { Write-Output "$($env:COMPUTERNAME): found $($SetupName) at $($FileOutPath), removing the files because too old" Remove-Item -Path $FileOutPath -Recurse -Force | Out-Null } } Write-Output "$($env:COMPUTERNAME): downloading from $($DownloadURL) to $($FileOutPath)" $ProgressPreference = "SilentlyContinue" Invoke-WebRequest -UseBasicParsing -Uri $DownloadURL -OutFile $FileOutPath $ProgressPreference = "Continue" Write-Output "$($env:COMPUTERNAME): download finished" } catch { throw "error downloading - $($PSItem.Exception.Message)" } } function Confirm-LatestModuleVersionInstalled { # https://blog.it-koehler.com/en/Archive/3359 [CmdletBinding()] param ( [Parameter()] [string] $ModuleName ) try { if ($null -eq (Get-Module -Name $ModuleName -ListAvailable)) { throw "$($env:COMPUTERNAME): module $($ModuleName) not installed" } # test connectivity try { $ConTestResult = Invoke-WebRequest -Uri "https://www.powershellgallery.com" -UseBasicParsing if($null -ne $ConTestResult.content) { $RunUpdate = $true } else { $RunUpdate = $false } } catch { $RunUpdate = $false } if ($RunUpdate -eq $true) { try { #getting version of installed module $version = (Get-Module -Name $ModuleName -ListAvailable) | Sort-Object Version -Descending | Select-Object Version -First 1 #converting version to string $stringver = $version | Select-Object @{n = 'ModuleVersion'; e = { $PSItem.Version -as [string] } } $a = $stringver | Select-Object Moduleversion -ExpandProperty Moduleversion #getting latest module version from ps gallery $psgalleryversion = Find-Module -Name $ModuleName -Repository PSGallery | Sort-Object Version -Descending | Select-Object Version -First 1 #converting version to string $onlinever = $psgalleryversion | Select-Object @{n = 'OnlineVersion'; e = { $PSItem.Version -as [string] } } $b = $onlinever | Select-Object OnlineVersion -ExpandProperty OnlineVersion } catch { throw "error collecting versions" } try { if ([version]"$($a)" -ge [version]"$($b)") { Write-Output "$($env:COMPUTERNAME): using $($ModuleName) with version $($a)" } else { Write-Output "$($env:COMPUTERNAME): the installed version of $($ModuleName) is not the latest" Write-Output "$($env:COMPUTERNAME): the one installed locally ($($a)) is lower than the one on the PowerShellGallery ($($b))" #ask for update do { $askyesno = (Read-Host "$($env:COMPUTERNAME): do you want to update Module $ModuleName (Y/N)").ToLower() } while ($askyesno -notin @('y', 'n')) if ($askyesno -eq 'y') { Write-Output "$($env:COMPUTERNAME): updating module $($ModuleName)" Update-Module -Name $ModuleName -Force } else { Write-Output "$($env:COMPUTERNAME): skipping update of module $($ModuleName)" } } if ($null -ne (Get-Module -Name $ModuleName)) { Remove-Module -Name $ModuleName -ErrorAction SilentlyContinue } } catch { throw "error updating module - $($PSItem.Exception.Message)" } } else { do { $askyesno = (Read-Host "$($env:COMPUTERNAME): could not connect to powershell gallery, still continue? (Y/N)").ToLower() } while ($askyesno -notin @('y', 'n')) if ($askyesno -eq 'y') { $version = (Get-Module -Name $ModuleName -ListAvailable) | Sort-Object Version -Descending | Select-Object Version -First 1 $stringver = $version | Select-Object @{n = 'ModuleVersion'; e = { $PSItem.Version -as [string] } } $a = $stringver | Select-Object Moduleversion -ExpandProperty Moduleversion Write-Output "$($env:COMPUTERNAME): using $($ModuleName) with version $($a)" } else { throw "$($env:COMPUTERNAME): stopping script, because could not connect to powershell gallery to get latest version of the $($ModuleName)" } } } catch { throw $PSItem.Exception.Message } } |