PSCommonCore.psm1
<#
=========================================================================== Created with: SAPIEN Technologies, Inc., PowerShell Studio 2019 v5.6.166 Created on: 8/6/2019 11:59 AM Created by: Gary Cook Organization: Quest Filename: PSCommonCore.psm1 ------------------------------------------------------------------------- Module Name: PSCommonCore =========================================================================== #requires the PShellLogging module found on the Powershell Gallery #> #.EXTERNALHELP PSCommonCore.psm1-Help.xml function Measure-IOPS { param ( [parameter(Mandatory = $true)] [string]$Speed, [parameter(Mandatory = $false)] [string]$SectorSize = "4K" ) BEGIN { } PROCESS { # Convert Speed to value and type [double]$Value = $Speed -replace '[^0-9,.]', '' $type = $Speed -replace '[0-9,., ]', '' $size = $type.substring(0,1) #check to see if the B is Capital if ($type -cmatch "B") { [int]$factor = 1 } else { [int]$factor = 8 } switch -casesensitive ($size) { b { $Value = $Value /$factor / 1024 / 1024 } B { $value = $Value /$factor / 1024 / 1024 } k { $Value = $Value /$factor / 1024 } K { $Value = $Value /$factor / 1024 } M { $Value = $Value /$factor } m { $Value = $Value /$factor } g { $Value = $Value /$factor * 1024 } G { $Value = $Value /$factor * 1024 } } [int]$Sector = $SectorSize -replace '[^0-9]', '' $Sector = $Sector * 1024 Write-Host "Calulating for Sector size of $($Sector)" Write-Host "A throughput of $($Speed) in IOPS is:" [double]$IOPS = ($Value / ($sector / 1024)) * 1024 Write-Host "$([math]::Round($IOPS, 2))" } END { } } #.EXTERNALHELP PSCommonCore.psm1-Help.xml function Connect-AD { param ( [parameter(Mandatory = $False, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true,Position = 1)] [Alias ('DC')] [string] $TargetDC = "", [parameter(Mandatory = $False, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 2)] [System.Management.Automation.PSCredential]$Credential ) BEGIN { if ($TargetDC -eq "") { $SystemDomainInfo = gwmi -Class win32_ntdomain if ($SystemDomainInfo.domaincontrollername -ne $null) { $TargetDC = $SystemDomainInof.domaincontrollername -replace "\\", "" $TargetDC = "$($TargetDC).$($SystemDomainInfo.dnsforestname)" } else { Write-Error "This Computer is not domain joined and no TargetDC (DC) was supplied. Error - Cannot connect to domain controller" end } } if ($Credential -eq $null) { $Credential = Get-Credential -Message "Please Enter you admin password for domain controller $($TargetDC)" } } PROCESS { try { $ErrorActionPreference = 'Stop' $session = New-PSSession -ComputerName $targetDC -Credential $Credential Invoke-Command $session -Scriptblock { Import-Module ActiveDirectory } #Import-PSSession -Session $session -AllowClobber $good = $true } catch { Write-Error "Failed to connect to domain controller $($TargetDC)" Write-Error "$($_.ErrorDetails.Message)" $good = $false } $session = Get-PSSession | ?{ $_.ComputerName -eq $TargetDC } <#if ($good) { Import-PSSession -Session $session -AllowClobber -module activedirectory }#> return $session } END { } } #.EXTERNALHELP PSCommonCore.psm1-Help.xml function export-AutodiscoverSPC { param ( [parameter(Mandatory = $false)] [string] $DomainDN ) $obj = @() if ($DomainDN -eq "") { $ADDomain = Get-ADDomain | Select DistinguishedName $DomainDN = $ADDomain.distinguishedname } $DSSearch = New-Object System.DirectoryServices.DirectorySearcher $DSSearch.Filter = '(&(objectClass=serviceConnectionPoint)(|(keywords=67661d7F-8FC4-4fa7-BFAC-E1D7794C1F68)(keywords=77378F46-2C66-4aa9-A6A6-3E7A48B19596)))' $DSSearch.SearchRoot = 'LDAP://CN=Configuration,' + $DomainDN $DSSearch.FindAll() | %{ $ADSI = [ADSI]$_.Path $autodiscover = New-Object psobject -Property @{ Server = [string]$ADSI.cn Site = $adsi.keywords[0] DateCreated = $adsi.WhenCreated.ToShortDateString() AutoDiscoverInternalURI = [string]$adsi.ServiceBindingInformation } $obj += $autodiscover } return $obj } #.EXTERNALHELP PSCommonCore.psm1-Help.xml Function Test-Module { param ( [parameter(Mandatory = $true)] [string]$Module, [parameter(Mandatory = $true)] [bool]$Load = $false ) [CmdletBinding] $Return = New-Object System.Management.Automation.PSObject $Return | Add-Member -MemberType NoteProperty -Name Status -Value $null $Return | Add-Member -MemberType NoteProperty -Name Message -Value $null if (!(get-module $Module)) { If (!(Get-Module -ListAvailable $Module)) { $Return.Status = "Not Loaded" $Return.Message = "The Module $($Module) was not available to load" } else { if ($Load -eq $true) { Import-Module ActiveDirectory -ErrorAction SilentlyContinue if (!(Get-Module activedirectory)) { $Return.Status = "Not Loaded" $Return.Message = "The Module $($Module) was available but failed to load" } else { $Return.Status = "Loaded" $Return.Message = "Module $($Module) was loaded successfully" } } else { $Return.Status = "Not Loaded" $Return.Message = "The Module $($Module) was available but not loaded due to switch" } } } else { $Return.Status = "Loaded" $Return.Message = "Module $($Module) was already loaded" } return $Return } #.EXTERNALHELP PSCommonCore.psm1-Help.xml function Test-PSVersion { param ( [parameter(Mandatory = $true)] [string]$Min, [parameter(Mandatory = $true)] [ValidateSet("Desktop","Core")] [string]$Edition = "Desktop" ) if ($Min.contains(".") -eq $true) { #Write-Host "Checking Powershell against $($Min)" $Major = ($Min -split "\.")[0] #Write-Host "Major Version: $($Major)" $Minor = ($Min -split "\.")[1] #Write-Host "Minor Version: $($Minor)" } else { #Write-Host "Checking Powershell against $($Min)" $Major = $Min #Write-Host "Major Version: $($Major)" $Minor = "0" #Write-Host "Minor Version: $($Minor)" } $Version = $PSVersionTable.pscompatibleversions $Return = $false #Write-Host "Processing PowerShell Compatable Versions" foreach ($V in $Version) { #Write-Host "Checking Version Major:$($V.major) Minor:$($V.minor)" if ($V.major -eq $Major -and $V.minor -eq $Minor) { #Write-Host "Matches Minimum Version" $Return = $true } } if ($Edition -eq $PSVersionTable.PSEdition) { return $Return } else { return $false } } #.EXTERNALHELP PSCommonCore.psm1-Help.xml function Write-Color([String[]]$Text, [ConsoleColor[]]$Color = (get-host).ui.rawui.ForegroundColor, [ConsoleColor[]]$BackColor = (get-host).ui.rawui.BackgroundColor, [int]$StartTab = 0, [int]$LinesBefore = 0, [int]$LinesAfter = 0) { $DefaultColor = $Color[0] $DefaultBackColor = $BackColor[0] if ($LinesBefore -ne 0) { for ($i = 0; $i -lt $LinesBefore; $i++) { Write-Host "`n" -NoNewline } } # Add empty line before if ($StartTab -ne 0) { for ($i = 0; $i -lt $StartTab; $i++) { Write-Host "`t" -NoNewLine } } # Add TABS before text if ($Color.Count -ge $Text.Count -and $BackColor.count -ge $Text.count) { for ($i = 0; $i -lt $Text.Length; $i++) { Write-Host $Text[$i] -ForegroundColor $Color[$i] -backgroundcolor $BackColor[$i] -NoNewLine } } else { if ($Color.Count -ge $Text.Count -and $BackColor.Count -lt $Text.Count) { for ($i = 0; $i -lt $BackColor.Length; $i++) { Write-Host $Text[$i] -ForegroundColor $Color[$i] -BackgroundColor $BackColor[$i] -NoNewLine } for ($i = $BackColor.Length; $i -lt $Text.Length; $i++) { Write-Host $Text[$i] -ForegroundColor $Color[$i] -BackgroundColor $DefaultBackColor -NoNewLine } } if ($Color.Count -lt $Text.Count -and $BackColor.Count -ge $Text.Count) { for ($i = 0; $i -lt $Color.Length; $i++) { Write-Host $Text[$i] -ForegroundColor $Color[$i] -BackgroundColor $BackColor[$i] -NoNewLine } for ($i = $BackColor.Length; $i -lt $Text.Length; $i++) { Write-Host $Text[$i] -ForegroundColor $DefaultColor -BackgroundColor $BackColor[$i] -NoNewLine } } if ($Color.Count -lt $Text.Count -and $BackColor.Count -lt $Text.Count) { if ($Color.Count -lt $BackColor.count) { for ($i = 0; $i -lt $Color.Length; $i++) { Write-Host $Text[$i] -ForegroundColor $Color[$i] -BackgroundColor $BackColor[$i] -NoNewLine } for ($i = $Color.Length; $i -lt $BackColor.length; $i++) { Write-Host $Text[$i] -ForegroundColor $DefaultColor -BackgroundColor $BackColor[$i] -NoNewLine } for ($i = $BackColor.Length; $i -lt $Text.length; $i++) { Write-Host $Text[$i] -ForegroundColor $DefaultColor -BackgroundColor $DefaultBackColor -NoNewLine } } if ($Color.Count -gt $BackColor.count) { for ($i = 0; $i -lt $BackColor.Length; $i++) { Write-Host $Text[$i] -ForegroundColor $Color[$i] -BackgroundColor $BackColor[$i] -NoNewLine } for ($i = $BackColor.Length; $i -lt $Color.length; $i++) { Write-Host $Text[$i] -ForegroundColor $Color[$i] -BackgroundColor $DefaultBackColor -NoNewLine } for ($i = $Color.Length; $i -lt $Text.length; $i++) { Write-Host $Text[$i] -ForegroundColor $DefaultColor -BackgroundColor $DefaultBackColor -NoNewLine } } if ($Color.Count -eq $BackColor.count) { for ($i = 0; $i -lt $BackColor.Length; $i++) { Write-Host $Text[$i] -ForegroundColor $Color[$i] -BackgroundColor $BackColor[$i] -NoNewLine } for ($i = $BackColor.Length; $i -lt $text.length; $i++) { Write-Host $Text[$i] -ForegroundColor $DefaultColor -BackgroundColor $DefaultBackColor -NoNewLine } } } } Write-Host if ($LinesAfter -ne 0) { for ($i = 0; $i -lt $LinesAfter; $i++) { Write-Host "`n" } } # Add empty line after } #.EXTERNALHELP PSCommonCore.psm1-Help.xml function Connect-Exchange { param ( [parameter(Mandatory = $false)] [System.Management.Automation.PSCredential]$Credential, [parameter(Mandatory = $false)] [ValidateSet ("EONPREM", "EOL")] [string]$Type = "EONPREM" ) Begin { if ($Credential -eq $null) { $Credential = Get-Credential -Message "Please Enter your Exchange Admin Credential." } } Process { try { $ErrorActionPreference = 'Stop' if ($Type -eq "EOL") { $Session = New-PSSession -ConfigurationName "Microsoft.Exchange" -ConnectionUri "https://outlook.office365.com/powershell-liveid/" -Credential $Credential -Authentication Basic -AllowRedirection } else { $server = Read-Host "Please enter On Prem Exchange Server Name" $Session = New-PSSession -ConfigurationName "Microsoft.Exchange" -ConnectionUri "https://$($server)/powershell/" -Credential $Credential -AllowRedirection } #Invoke-Command $session -Scriptblock {"1"} $good = $true } catch { Write-Error "Failed to connect to Exchange" Write-Error "$($_.ErrorDetails.Message)" $good = $false } #[int]$rtvalue = $Session.Id #Write-Host "The Session id is $($rtvalue)" #$null = Import-PSSession $Session -DisableNameChecking -AllowClobber #$session = Get-PSSession | ?{ $_.ConfigurationName -eq "Microsoft.Exchange" } | select -First 1 <#if ($good) { Import-PSSession -Session $session -AllowClobber -DisableNameChecking }#> return $session } END { } } #.EXTERNALHELP PSCommonCore.psm1-Help.xml function Disconnect-Exchange { param ( [parameter(Mandatory = $true,ValueFromPipeline = $true)] [int]$SessionId ) $session = Get-PSSession |?{$_.Id -eq $SessionId} Remove-PSSession -Session $Session } #.EXTERNALHELP PSCommonCore.psm1-Help.xml function Start-Log { <# .SYNOPSIS Creates the supplied log file $Log. .DESCRIPTION .PARAMETER $Log the complete path to the log to write to. required. $type the type of log file to generate TXT is assumed. Possible Values are TXT, CSV, JSON. .EXAMPLE creates a log at location and returns object representing the log and type Start-Log -Log "C:\applog.txt" -Type CSV .NOTES FunctionName : Write-Log Created by : Gary Cook Date Coded : 07/26/2019 .OUTPUTS Returns and object containing the path to the log and the type of the log. #> [CmdletBinding()] Param ( [parameter (position = 0, Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [string]$Log, [Parameter (Position = 1, Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [ValidateSet("TXT", "CSV", "JSON")] [string]$Type = "TXT" ) Begin { } Process { # Format Date for our Log File $FormattedDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss" #if log does not exists create log with application runtime banner if (!(Test-Path $Log -PathType Leaf)) { if (!(Test-Path $Log)) { #create file including path if the path does not exist $NewLogFile = New-Item $Log -Force -ItemType File } if ($Type -eq "TXT") { #create file with banner $Banner = "*************************************************" $Banner | Out-File -FilePath $Log -Append -force $Banner = "Application log created $($FormattedDate) on computer $($env:COMPUTERNAME)" $Banner | Out-File -FilePath $Log -Append $Banner = "*************************************************" $Banner | Out-File -FilePath $Log -Append } if ($Type -eq "CSV") { #open out file with headder $Banner = "Date,Level,Message" $Banner | Out-File -FilePath $Log -Append -force $Banner = "$($FormattedDate),INFO:,Application Log file Created for computer $($env:COMPUTERNAME)" $Banner | Out-File -FilePath $Log -Append } if ($Type -eq "JSON") { $Banner = "{`"DATE`": `"$($FormattedDate)`",`"LEVEL`": `"INFO:`",`"MESSAGE`": `"Application Log file Created for computer $($env:COMPUTERNAME)`"}" $Banner | Out-File -FilePath $Log -Append -force } } $obj = new-object System.Management.Automation.PSObject $obj | Add-Member -MemberType NoteProperty -Name Log -Value (get-item $log).VersionInfo.filename $obj | Add-Member -MemberType NoteProperty -Name Type -Value $Type return $obj } end { } } #.EXTERNALHELP PSCommonCore.psm1-Help.xml Function Write-Log { <# .SYNOPSIS Writes the Entry in $Line to the supplied log file $Log. Built to take pipeline input from object returned from start-log. .DESCRIPTION .PARAMETER $Line String of data to write to the log file. required. $Log the complete path to the log to write to. required. $Level The type of line to write to the log. Valid vales are Error,Warn,Info. Default is Info. $Type the type of log file to generate TXT is assumed. Possible Values are TXT, CSV, JSON. .EXAMPLE $mylog | Write-Log -Line "This is an entry for the log" -level Info .NOTES FunctionName : Write-Log Created by : Gary Cook Date Coded : 07/26/2019 .OUTPUTS Returns 0 if log exists or -1 if the log file does not exist #> [CmdletBinding()] Param ( [parameter (position = 0, Mandatory = $true)] [string]$Line, [parameter (position = 1, Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [string]$Log, [Parameter (position = 2, Mandatory = $false)] [ValidateSet("Error", "Warn", "Info")] [string]$Level = "Info", [Parameter (Position = 3, Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [ValidateSet("TXT", "CSV", "JSON")] [string]$Type = "TXT" ) Begin { } Process { # Format Date for our Log File $FormattedDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss" # Write message to error, warning, or verbose pipeline and specify $LevelText switch ($Level) { 'Error' { $LevelText = 'ERROR:' } 'Warn' { $LevelText = 'WARNING:' } 'Info' { $LevelText = 'INFO:' } } #if log does not exists reutrn -1 else return 0 if (!(Test-Path $Log -PathType Leaf)) { if (!(Test-Path $Log)) { return -1 break } } # Write message to proper log type switch ($Type) { 'TXT' { "$($FormattedDate) $($LevelText) $($Line)" | Out-File -FilePath $Log -Append } 'CSV' { "$($FormattedDate),$($LevelText),$($Line)" | Out-File -FilePath $Log -Append } 'JSON' { "{`"DATE`": `"$($FormattedDate)`",`"LEVEL`": `"$($LevelText)`",`"MESSAGE`": `"$($Line)`"}" | Out-File -FilePath $Log -Append } } return 0 } End { } } #.EXTERNALHELP PSCommonCore.psm1-Help.xml Function Close-Log { <# .SYNOPSIS Closes the supplied log file $Log. Built to take pipeline input from object returned from start-log. .DESCRIPTION .PARAMETER $Log the complete path to the log to write to. required. $Type the type of log file to generate TXT is assumed. Possible Values are TXT, CSV, JSON. .EXAMPLE $mylog | Close-Log .NOTES FunctionName : Write-Log Created by : Gary Cook Date Coded : 07/26/2019 #> [CmdletBinding()] Param ( [parameter (position = 0, Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [string]$Log, [Parameter (Position = 1, Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [ValidateSet("TXT", "CSV", "JSON")] [string]$Type = "TXT" ) Begin { } Process { # Format Date for our Log File $FormattedDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss" if ($Type -eq "TXT") { #close out file with footer $Footer = "*************************************************" $Footer | Out-File -FilePath $Log -Append $Footer = "Application log end $($FormattedDate) on computer $($env:COMPUTERNAME)" $Footer | Out-File -FilePath $Log -Append $Footer = "*************************************************" $Footer | Out-File -FilePath $Log -Append } if ($Type -eq "CSV") { #close out file with footer $Footer = "$($FormattedDate),INFO:,Application Log file end for computer $($env:COMPUTERNAME)" $Footer | Out-File -FilePath $Log -Append } if ($Type -eq "JSON") { $Footer = "{`"DATE`": `"$($FormattedDate)`",`"LEVEL`": `"INFO:`",`"MESSAGE`": `"Application Log file end for computer $($env:COMPUTERNAME)`"}" $Footer | Out-File -FilePath $Log -Append } } End { } } #.EXTERNALHELP PSCommonCore.psm1-Help.xml function New-RandomString([string]$inputString) { $characterArray = $inputString.ToCharArray() $scrambledStringArray = $characterArray | Get-Random -Count $characterArray.Length $outputString = -join $scrambledStringArray return $outputString } #.EXTERNALHELP PSCommonCore.psm1-Help.xml function Get-RandomCharacters($length, $characters) { $random = 1 .. $length | ForEach-Object { Get-Random -Maximum $characters.length } $private:ofs = "" return [String]$characters[$random] } #.EXTERNALHELP PSCommonCore.psm1-Help.xml function New-password { param ( [parameter(Mandatory = $true)] [int]$Length, [parameter(Mandatory = $false)] [switch]$Upper = $false, [parameter(Mandatory = $false)] [switch]$Lower = $false, [parameter(Mandatory = $false)] [switch]$Number = $false, [parameter(Mandatory = $false)] [switch]$Symbol = $false, [parameter(Mandatory = $false)] [int]$MinLower = 1, [parameter(Mandatory = $false)] [int]$MinUpper = 1, [parameter(Mandatory = $false)] [int]$MinNumber = 1, [parameter(Mandatory = $false)] [int]$MinSymbol = 1, [parameter(Mandatory = $false)] [switch]$NonAmbiguous = $false ) if ($Upper -eq $false -and $Lower -eq $false -and $Number -eq $false -and $Symbol -eq $false) { Write-Error "Must Specify at least one character type for password i.e. -lower in call to new-password" } else { # Fix password length if minchars is more than length $BaseCount = 1 if ($Upper) { $BaseCount += $MinUpper } if ($Lower) { $BaseCount += $MinLower } if ($Number) { $BaseCount += $MinNumber } if ($Symbol) { $BaseCount += $MinSymbol } if ($BaseCount -gt $Length) { $Length = $BaseCount } $remaining = $Length - $BaseCount # Creates character arrays for the different character classes, based on ASCII character values. [string]$charsLower = (97 .. 122 | %{ [Char]$_ }) $charsLower = $charsLower -replace " ", "" [string]$charsUpper = (65 .. 90 | %{ [Char]$_ }) $charsUpper = $charsUpper -replace " ", "" [string]$charsNumber = (48 .. 57 | %{ [Char]$_ }) $charsNumber = $charsNumber -replace " ", "" [string]$charsSymbol = (35, 36, 40, 41, 42, 44, 45, 46, 47, 58, 59, 63, 64, 92, 95 | %{ [Char]$_ }) $charsSymbol = $charsSymbol -replace " ", "" # Create character arrays for non ambiguous characters l (ell), 1 (one), I (capital i), O (capital o), 0 (zero), B (capital b), 8 (eight), q (queue), g (gee), | (pipe) [string]$charsLowera = "abcdefhijkmnoprstuvwxyz" $charsLowera = $charsLowera -replace " ", "" [string]$charsUppera = "ACDEFGHJKLMNPQRTUVWXYZ" $charsUppera = $charsUppera -replace " ", "" [string]$charsNumbera = "234679" $charsNumbera = $charsNumbera -replace " ", "" [string]$charsSymbola = "!@#$%^&*()-=+:,?_.~" $charsSymbola = $charsSymbola -replace " ", "" if ($NonAmbiguous -eq $false) { if ($Upper) { $RandomUString = Get-RandomCharacters -length $MinUpper -characters $charsUpper } else { $RandomUString = "" } if ($Lower) { $RandomLString = Get-RandomCharacters -length $MinLower -characters $charsLower } else { $RandomLString = "" } if ($Number) { $RandomNString = Get-RandomCharacters -length $MinNumber -characters $charsNumber } else { $RandomNString = "" } if ($Symbol) { $RandomSString = Get-RandomCharacters -length $MinSymbol -characters $charsSymbol } else { $RandomSString = "" } if ($remaining -gt 0) { $Tempc = "" if ($Upper) { $Tempc += $charsUpper } if ($Lower) { $Tempc += $charsLower } if ($Number) { $Tempc += $charsNumber } if ($Symbol) { $Tempc += $charsSymbol } $RandomString = Get-RandomCharacters -length $remaining -characters $Tempc } else { $RandomString = "" } } else { if ($Upper) { $RandomUString = Get-RandomCharacters -length $MinUpper -characters $charsUppera } else { $RandomUString = "" } if ($Lower) { $RandomLString = Get-RandomCharacters -length $MinLower -characters $charsLowera } else { $RandomLString = "" } if ($Number) { $RandomNString = Get-RandomCharacters -length $MinNumber -characters $charsNumbera } else { $RandomNString = "" } if ($Symbol) { $RandomSString = Get-RandomCharacters -length $MinSymbol -characters $charsSymbola } else { $RandomSString = "" } if ($remaining -gt 0) { $Tempc = "" if ($Upper) { $Tempc += $charsUppera } if ($Lower) { $Tempc += $charsLowera } if ($Number) { $Tempc += $charsNumbera } if ($Symbol) { $Tempc += $charsSymbola } $RandomString = Get-RandomCharacters -length $remaining -characters $Tempc } else { $RandomString = "" } } #combine all into a single string $Return = $RandomUString + $RandomLString + $RandomNString + $RandomSString + $RandomString #scramble the scring $Return = New-RandomString -inputString $Return return $Return } } #.EXTERNALHELP PSCommonCore.psm1-Help.xml function get-loggedonuser () { [CmdletBinding()] Param ( [parameter (position = 0, Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [string]$computername , [Parameter (Position = 1, Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [ValidateSet($true,$false)] [bool]$local = $false, [Parameter (Position = 2, Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [System.Management.Automation.PSCredential]$credential ) Begin { } Process { if ($local -eq $false -and $computername -eq $null) { $computername = Read-Host "Remote computername was not provided please enter remote computername" if ($computername -eq "") { Write-Host "Computername not provided exiting" end } } if ($credential -eq $null) { write-host "User Credential not provided using logged on user" $localuser = $true } $regexa = '.+Domain="(.+)",Name="(.+)"$' $regexd = '.+LogonId="(\d+)"$' $logontype = @{ "0" = "Local System" "2" = "Interactive" #(Local logon) "3" = "Network" # (Remote logon) "4" = "Batch" # (Scheduled task) "5" = "Service" # (Service account logon) "7" = "Unlock" #(Screen saver) "8" = "NetworkCleartext" # (Cleartext network logon) "9" = "NewCredentials" #(RunAs using alternate credentials) "10" = "RemoteInteractive" #(RDP\TS\RemoteAssistance) "11" = "CachedInteractive" #(Local w\cached credentials) } switch ($local) { $true { $logon_sessions = @(gwmi win32_logonsession -ComputerName "localhost") $logon_users = @(gwmi win32_loggedonuser -ComputerName "localhost") } $false { if ($localuser -ne $true) { $logon_sessions = @(gwmi win32_logonsession -ComputerName $computername -Credential $credential) $logon_users = @(gwmi win32_loggedonuser -ComputerName $computername -Credential $credential) } else { $logon_sessions = @(gwmi win32_logonsession -ComputerName $computername ) $logon_users = @(gwmi win32_loggedonuser -ComputerName $computername ) } } } $session_user = @{ } $logon_users | % { $_.antecedent -match $regexa > $nul $username = $matches[1] + "\" + $matches[2] $_.dependent -match $regexd > $nul $session = $matches[1] $session_user[$session] += $username } $logon_sessions | %{ $starttime = [management.managementdatetimeconverter]::todatetime($_.starttime) $loggedonuser = New-Object -TypeName psobject $loggedonuser | Add-Member -MemberType NoteProperty -Name "Session" -Value $_.logonid $loggedonuser | Add-Member -MemberType NoteProperty -Name "User" -Value $session_user[$_.logonid] $loggedonuser | Add-Member -MemberType NoteProperty -Name "Type" -Value $logontype[$_.logontype.tostring()] $loggedonuser | Add-Member -MemberType NoteProperty -Name "Auth" -Value $_.authenticationpackage $loggedonuser | Add-Member -MemberType NoteProperty -Name "StartTime" -Value $starttime $loggedonuser } } end { } } #.EXTERNALHELP PSCommonCore.psm1-Help.xml Function Set-Owner { <# .SYNOPSIS Changes owner of a file or folder to another user or group. .DESCRIPTION Changes owner of a file or folder to another user or group. .PARAMETER Path The folder or file that will have the owner changed. .PARAMETER Account Optional parameter to change owner of a file or folder to specified account. Default value is 'Builtin\Administrators' .PARAMETER Recurse Recursively set ownership on subfolders and files beneath given folder. .NOTES Name: Set-Owner Author: Boe Prox Version History: 1.0 - Boe Prox - Initial Version 2.0 - Gary Cook - Added PShellLogging to capture Success and Error Information - Fixed issues processing owner on specific server OS's Requires the PSHellLogging Modules Available on PowerShell gallery https://www.powershellgallery.com/packages/PShellLogging/1.1.13 Use "Install-Module -Name PShellLogging" on powershell 5.0 and higher to install .EXAMPLE Set-Owner -Path C:\temp\test.txt -Log c:\logs\ownerlog.csv -logtype CSV Description ----------- Changes the owner of test.txt to Builtin\Administrators, Logs output to c:\logs\ownerlog.csv in comma Seperated Format .EXAMPLE Set-Owner -Path C:\temp\test.txt -Account 'Domain\bprox -Log c:\logs\ownerlog.TXT -logtype TXT Description ----------- Changes the owner of test.txt to Domain\bprox, Logs output to c:\logs\ownerlog.csv in text format .EXAMPLE Set-Owner -Path C:\temp -Recurse -Log c:\logs\ownerlog.csv -logtype CSV Description ----------- Changes the owner of all files and folders under C:\Temp to Builtin\Administrators, Logs output to c:\logs\ownerlog.csv in comma Seperated Format .EXAMPLE Get-ChildItem C:\Temp | Set-Owner -Recurse -Account 'Domain\bprox' -Log c:\logs\ownerlog.csv -logtype CSV Description ----------- Changes the owner of all files and folders under C:\Temp to Domain\bprox, Logs output to c:\logs\ownerlog.csv in comma Seperated Format #> [cmdletbinding( SupportsShouldProcess = $True )] Param ( [parameter(mandatory = $true, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] [Alias('FullName')] [string[]]$Path, [parameter()] [string]$Account = 'Builtin\Administrators', [parameter()] [switch]$Recurse, [parameter()] [string]$Log, [parameter()] [ValidateSet("TXT", "CSV", "JSON")] [string]$logtype = "CSV" ) Begin { #Create Log if necessary if ($Log -ne $null) { $MyLog = Start-Log -Log $Log -Type $logtype $logging = $true } #Prevent Confirmation on each Write-Debug command when using -Debug If ($PSBoundParameters['Debug']) { $DebugPreference = 'Continue' } Try { [void][TokenAdjuster] } Catch { $AdjustTokenPrivileges = @" using System; using System.Runtime.InteropServices; public class TokenAdjuster { [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen); [DllImport("kernel32.dll", ExactSpelling = true)] internal static extern IntPtr GetCurrentProcess(); [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok); [DllImport("advapi32.dll", SetLastError = true)] internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid); [StructLayout(LayoutKind.Sequential, Pack = 1)] internal struct TokPriv1Luid { public int Count; public long Luid; public int Attr; } internal const int SE_PRIVILEGE_DISABLED = 0x00000000; internal const int SE_PRIVILEGE_ENABLED = 0x00000002; internal const int TOKEN_QUERY = 0x00000008; internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; public static bool AddPrivilege(string privilege) { try { bool retVal; TokPriv1Luid tp; IntPtr hproc = GetCurrentProcess(); IntPtr htok = IntPtr.Zero; retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok); tp.Count = 1; tp.Luid = 0; tp.Attr = SE_PRIVILEGE_ENABLED; retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid); retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero); return retVal; } catch (Exception ex) { throw ex; } } public static bool RemovePrivilege(string privilege) { try { bool retVal; TokPriv1Luid tp; IntPtr hproc = GetCurrentProcess(); IntPtr htok = IntPtr.Zero; retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok); tp.Count = 1; tp.Luid = 0; tp.Attr = SE_PRIVILEGE_DISABLED; retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid); retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero); return retVal; } catch (Exception ex) { throw ex; } } } "@ Add-Type $AdjustTokenPrivileges } #Activate necessary admin privileges to make changes without NTFS perms [void][TokenAdjuster]::AddPrivilege("SeRestorePrivilege") #Necessary to set Owner Permissions [void][TokenAdjuster]::AddPrivilege("SeBackupPrivilege") #Necessary to bypass Traverse Checking [void][TokenAdjuster]::AddPrivilege("SeTakeOwnershipPrivilege") #Necessary to override FilePermissions } Process { ForEach ($Item in $Path) { Write-Verbose "FullName: $Item" if ($logging) { $MyLog | Write-Log -Line "Proicessing item $($Item)" -Level Info } #The ACL objects do not like being used more than once, so re-create them on the Process block $DirOwner = New-Object System.Security.AccessControl.DirectorySecurity $DirOwner.SetOwner([System.Security.Principal.NTAccount]$Account) $FileOwner = New-Object System.Security.AccessControl.FileSecurity $FileOwner.SetOwner([System.Security.Principal.NTAccount]$Account) $DirAdminAcl = New-Object System.Security.AccessControl.DirectorySecurity $FileAdminAcl = New-Object System.Security.AccessControl.DirectorySecurity $AdminACL = New-Object System.Security.AccessControl.FileSystemAccessRule('Builtin\Administrators', 'FullControl', 'ContainerInherit,ObjectInherit', 'InheritOnly', 'Allow') $FileAdminAcl.AddAccessRule($AdminACL) $DirAdminAcl.AddAccessRule($AdminACL) Try { $Item = Get-Item -LiteralPath $Item -Force -ErrorAction Stop If (-NOT $Item.PSIsContainer) { If ($PSCmdlet.ShouldProcess($Item, 'Set File Owner')) { Try { $Item.SetAccessControl($FileOwner) } Catch { Write-Warning "Couldn't take ownership of $($Item.FullName)! Taking FullControl of $($Item.Directory.FullName)" $Item.Directory.SetAccessControl($FileAdminAcl) $Item.SetAccessControl($FileOwner) } } } Else { If ($PSCmdlet.ShouldProcess($Item, 'Set Directory Owner')) { Try { $Item.SetAccessControl($DirOwner) } Catch { Write-Warning "Couldn't take ownership of $($Item.FullName)! Taking FullControl of $($Item.Parent.FullName)" $Item.Parent.SetAccessControl($DirAdminAcl) $Item.SetAccessControl($DirOwner) } } If ($Recurse) { [void]$PSBoundParameters.Remove('Path') Get-ChildItem $Item -Force | Set-Owner @PSBoundParameters } } if ($logging) { $MyLog | Write-Log -Line "Item $($Item) was successfully processed" -Level Info } } Catch { Write-Warning "$($Item): $($_.Exception.Message)" if ($logging) { $MyLog | Write-Log -Line "Item $($Item) processing failed error message $($_.Exception.Message)" -Level Error } } } } End { #Remove priviledges that had been granted [void][TokenAdjuster]::RemovePrivilege("SeRestorePrivilege") [void][TokenAdjuster]::RemovePrivilege("SeBackupPrivilege") [void][TokenAdjuster]::RemovePrivilege("SeTakeOwnershipPrivilege") if ($logging) { $MyLog | Close-Log } } } #.EXTERNALHELP PSCommonCore.psm1-Help.xml function Test-ADUserExists { <# .SYNOPSIS Test the existance of an AD User by suppling the prapmeter and value to search .DESCRIPTION If one or more user(s) are present Returns the SID of the first user returned and count of users matching query. If no users match query return a count of 0. if any error occures diring execution returnes a count of -1 and an error message. .PARAMETER TargetDC The Target Domain Controller to execute the query against if no value is specified the result of get-addomaincontroller -discover will be used .PARAMETER ADProperty The Active Directory property to query. .PARAMETER Value The Value to search for in the suppied ADProperty .EXAMPLE PS C:\> Test-ADUserExists -Value 'Value1' .NOTES Additional information about the function. #> [CmdletBinding()] [OutputType([object])] param ( [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('DC')] [String]$TargetDC, [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [string]$ADProperty = 'SAMAccountName', [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [String]$Value ) Begin { if ($TargetDC -eq "") { $TargetDC = (Get-ADDomainController -Discover).hostname } } Process { try { $obj = New-Object System.Management.Automation.PSObject $propfilter = "SID","$($ADProperty)" $users = Get-ADUser -Filter * -Properties $propfilter -Server $TargetDC | ?{ $_.$ADProperty -eq $Value } -ea Stop $count = ($users | measure).count if ($count -ne 1) { if ($count -ne 0) { $obj | Add-Member -MemberType NoteProperty -Name SID -Value $users[0].sid.value $obj | Add-Member -MemberType NoteProperty -Name Count -Value $count $obj | Add-Member -MemberType NoteProperty -Name Error -Value "None" } else { $obj | Add-Member -MemberType NoteProperty -Name SID -Value "" $obj | Add-Member -MemberType NoteProperty -Name Count -Value $count $obj | Add-Member -MemberType NoteProperty -Name Error -Value "None" } } else { $obj | Add-Member -MemberType NoteProperty -Name SID -Value $users.sid.value $obj | Add-Member -MemberType NoteProperty -Name Count -Value $count $obj | Add-Member -MemberType NoteProperty -Name Error -Value "None" } } catch { $obj | Add-Member -MemberType NoteProperty -Name SID -Value "" $obj | Add-Member -MemberType NoteProperty -Name Count -Value -1 $obj | Add-Member -MemberType NoteProperty -Name Error -Value $_.ErrorDetails.Message } } End { return $obj } } #.EXTERNALHELP PSCommonCore.psm1-Help.xml function Test-Powershell { $obj = New-Object System.Management.Automation.PSObject $obj | Add-Member -MemberType NoteProperty -Name Version -Value "$($PSVersionTable.psversion.major).$($PSVersionTable.psversion.minor)" $obj | Add-Member -MemberType NoteProperty -Name Major -Value $PSVersionTable.psversion.major $obj | Add-Member -MemberType NoteProperty -Name Minor -Value $PSVersionTable.psversion.minor $obj | Add-Member -MemberType NoteProperty -Name Build -Value $PSVersionTable.psversion.build if ($PSVersionTable.psedition -eq $null) { $obj | Add-Member -MemberType NoteProperty -Name Edition -Value "Desktop" } else { $obj | Add-Member -MemberType NoteProperty -Name Edition -Value $PSVersionTable.psedition } if ($obj.edition -eq 'Core') { $obj | Add-Member -MemberType NoteProperty -Name Platform -Value $PSVersionTable.platform } else { $obj | Add-Member -MemberType NoteProperty -Name Platform -Value "Win32NT" } $obj | Add-Member -MemberType NoteProperty -Name Elevated -Value ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if ($obj.Elevated -eq $true) { $obj | Add-Member -MemberType NoteProperty -Name RemotingEnabled -Value (Test-PsRemoting) } else { $obj | Add-Member -MemberType NoteProperty -Name RemotingEnabled -Value "N/A" } return $obj } #.EXTERNALHELP PSCommonCore.psm1-Help.xml function Test-PsRemoting { param ( [Parameter(Mandatory = $false)] $computername = "Localhost", [Parameter(Mandatory = $false)] [switch]$Auth = $false, [Parameter(Mandatory = $false)] [System.Management.Automation.PSCredential]$credential ) try { $errorActionPreference = "Stop" if ($Auth) { if ($credential -eq $null) { $credential = Get-Credential } $result = Invoke-Command -ComputerName $computername -Credential $credential -scriptblock { 1 } } else { $result = Invoke-Command -ComputerName $computername -scriptblock { 1 } } } catch { Write-Verbose $_ return $false } ## I've never seen this happen, but if you want to be ## thorough.... if ($result -ne 1) { Write-Verbose "Remoting to $computerName returned an unexpected result." return $false } $true } #.EXTERNALHELP PSCommonCore.psm1-Help.xml function get-pagefilelocation { param ( [Parameter(Mandatory = $false)] $computername, [Parameter(Mandatory = $false)] [System.Management.Automation.PSCredential]$credential ) if ($computername -eq $null) { $computername = $env:computername } if ($credential -eq $null) { $loc = (Get-WmiObject -ComputerName $computername -Class Win32_PageFileUsage | select name).name return $loc } else { $loc = (Get-WmiObject -ComputerName $computername -Class Win32_PageFileUsage -Credential $credential | select name).name return $loc } } |