OSTools.psm1
$messages = DATA { # culture="de-de" ConvertFrom-StringData @" Connecting = Gonna talk to Failed = That did not work "@ } #Import-LocalizedData -BindingVariable messages function Get-SysDiskDetails { [CmdletBinding()] param ( [Alias("Name","Hostname")] [Parameter( Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true )] [string[]]$ComputerName = "localhost" ) PROCESS { foreach ($computer in $ComputerName) { Write-Verbose "$($messages.Connecting) $computer" try{ $os = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $computer -ErrorAction Stop $cs = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $computer $bios = Get-WmiObject -Class Win32_BIOS -ComputerName $computer $disks = Get-WmiObject -Class Win32_LogicalDisk -ComputerName $computer #First Create Nested Object $diskcollection = @() foreach ($disk in $disks) { $diskprops = @{ 'DriveLetter' = $disk.deviceid; 'DriveType' = $disk.DriveType; 'Size' = $disk.Size } $diskobj = New-Object -TypeName psobject -Property $diskprops $diskcollection += $diskobj } $props = @{ 'ComputerName' = $cs.__SERVER; 'OSVersion' = $os.version; 'SPVersion' = $os.servicepackmajorversion; 'OSBuild' = $os.buildnumber; 'Manufacturer' = $cs.Manufacturer; 'Model' = $cs.model; 'BIOSSerial' = $bios.serialnumber; 'Disks' = $diskcollection } $obj = New-Object -TypeName psobject -Property $props $obj.psobject.typenames.insert(0,'CriticalSolutions.OSTools.SysDiskDetails') Write-Output $obj } catch{ Write-Warning "$($messages.failed) $computer" } } } } function Get-SystemDetails { <# .SYNOPSIS Gets basic system information from one or more computers via WMI .DESCRIPTION See synopsis. This is not complex. .PARAMETER ComputerName The name of the Host to Query .EXAMPLE Get-SystemDetails -Computername DC Gets system info from the computer named DC. .INPUTS Inputs (if any) .OUTPUTS Output (if any) .NOTES General notes #> [CmdletBinding()] param ( [Alias("Name","Hostname")] [Parameter( Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true )] [string[]]$ComputerName = "localhost" ) PROCESS { foreach ($computer in $ComputerName) { $os = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $computer $cs = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $computer $bios = Get-WmiObject -Class Win32_BIOS -ComputerName $computer $props = @{ 'ComputerName' = $cs.__SERVER; 'OSVersion' = $os.version; 'SPVersion' = $os.servicepackmajorversion; 'OSBuild' = $os.buildnumber; 'Manufacturer' = $cs.Manufacturer; 'Model' = $cs.model; 'BIOSSerial' = $bios.serialnumber } $obj = New-Object -TypeName psobject -Property $props $obj.psobject.typenames.insert(0,'CriticalSolutions.OSTools.SystemDetails') Write-Output $obj } } }# function Get-DiskDetails { <# .SYNOPSIS Gets information on local disks. .DESCRIPTION See Synopsis, uses WMI. .PARAMETER ComputerName One or more Computers or IP's to query. .EXAMPLE Get-DiskDetails -ComputerName DC,CLIENT Get disk space details from Computers DC and CLIENT. .INPUTS Inputs (if any) .OUTPUTS Output (if any) .NOTES General notes #> [CmdletBinding()] param ( [Alias("Name","Hostname")] [Parameter( Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true )] [string[]]$ComputerName = "localhost" ) PROCESS { foreach ($computer in $ComputerName) { $disks = Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType='3'" -ComputerName $computer | Where-Object {$_.size -ne $null} $ram = (Get-WmiObject Win32_PhysicalMemory -ComputerName $computer | Measure-Object -Property capacity -Sum).sum /1gb foreach ($disk in $disks) { $props = @{ 'ComputerName' = $computer; 'Drive' = $disk.DeviceID; 'FreeSpace' = "{0:N2}" -f ($disk.FreeSpace / 1GB); 'Size' = "{0:N2}" -f ($disk.size / 1GB); 'FreePercent' = "{0:N2}" -f ($disk.FreeSpace / $disk.size * 100 -as [int]); 'Collected' = (Get-Date) 'Ram (GB)' = $ram } $obj = New-Object -TypeName psobject -Property $props $obj.psobject.typenames.insert(0,'Report.OSTools.DiskDetails') Write-Output $obj } } } } # function Save-DiskDetailsToDatabase { [CmdletBinding()] param ( [Parameter( Mandatory=$true, ValueFromPipeline=$true )] [object[]]$inputobject ) BEGIN { $connection = New-Object -TypeName System.Data.SqlClient.SqlConnection $connection.ConnectionString = "Server=CSNSQLU;Database=DiskDetails;User Id=pshell;Password=Wcdi2010!@#;" $connection.Open() | Out-Null } PROCESS{ $command = New-Object -TypeName System.Data.SqlClient.SqlCommand $command.Connection = $connection $sql = "DELETE FROM DiskData WHERE ComputerName = '$($inputobject.ComputerName)' AND DriveLetter = '$($inputobject.Drive)'" Write-Debug "Executing $sql" $command.CommandText = $sql $command.ExecuteNonQuery() | Out-Null $sql = "INSERT INTO DiskData ( ComputerName, DriveLetter, FreeSpace, Size, FreePercent ) VALUES( '$($inputobject.computername)', '$($inputobject.Drive)', '$($inputobject.FreeSpace)', '$($inputobject.Size)', '$($inputobject.FreePercent)' )" Write-Debug "Executing $sql" $command.CommandText = $sql $command.ExecuteNonQuery() | Out-Null } END { $connection.Close() } } function Get-ComputerNamesForDiskDetailsFromDatabase { $connection = New-Object -TypeName System.Data.SqlClient.SqlConnection $connection.ConnectionString = "Server=CSNSQLU;Database=DiskDetails;User Id=pshell;Password=Wcdi2010!@#;" $connection.Open() | Out-Null $command = New-Object -TypeName System.Data.SqlClient.SqlCommand $command.Connection = $connection $sql = "SELECT ComputerName FROM DiskData" Write-Debug "Executing $sql" $command.CommandText = $sql $reader = $command.ExecuteReader() while ($reader.read()) { $computername = $reader.GetSqlString(0).Value Write-Output $computername } $connection.Close() } function Set-ComputerState { [CmdletBinding( SupportsShouldProcess=$true,# Turns on Whatif ConfirmImpact='High' # and confirm. )] param ( [Parameter( Mandatory=$true, ValueFromPipeline=$true )] [string]$ComputerName, # Action [Parameter( Mandatory=$true )] [ValidateSet( 'LogOff', 'PowerOff', 'Shutdown', 'Restart' )] [string]$Action, [switch]$Force ) PROCESS{ foreach ($computer in $ComputerName) { switch ($Action) { 'LogOff' { $x = 0 } 'Shutdown' { $x = 1 } 'Restart' { $x = 2 } 'PowerOff' { $x = 8 } } if ($Force) { $x += 4 } $os = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $computer -EnableAllPrivileges if ($pscmdlet.ShouldProcess("$Action $computer")) { $os.Win32Shutdown($x) | Out-Null } } } } function Convert-WuaResultCodeToName { #doug rios modified param( [Parameter(Mandatory=$true)] [int] $ResultCode ) $Result = $ResultCode switch($ResultCode) { 2 {$Result = "Succeeded"} 3 {$Result = "Succeeded With Errors"} 4 {$Result = "Failed"} } return $Result } function Get-WuaHistory { # Get a WUA Session $session = (New-Object -ComObject 'Microsoft.Update.Session') # Query the latest History starting with the first record $history = $session.QueryHistory("",0,100) | ` ForEach-Object { $Result = Convert-WuaResultCodeToName -ResultCode $_.ResultCode # Make the properties hidden in com properties visible. $_ | Add-Member -MemberType NoteProperty -Value $Result -Name Result $Product = $_.Categories | Where-Object {$_.Type -eq 'Product'} | Select-Object -First 1 -ExpandProperty Name $KBs = $_.Title | Select-String -Pattern "KB\d*" $KB = $KBs.Matches.Value $_ | Add-Member -MemberType NoteProperty -Value $_.UpdateIdentity.UpdateId -Name UpdateId $_ | Add-Member -MemberType NoteProperty -Value $_.UpdateIdentity.RevisionNumber -Name RevisionNumber $_ | Add-Member -MemberType NoteProperty -Value $Product -Name Product -PassThru $_ | Add-Member -MemberType NoteProperty -Value $KB -Name KBArticle -PassThru Write-Output $_ } #Remove null records and only return the fields we want $history | Where-Object {![String]::IsNullOrWhiteSpace($_.title)} | Select-Object Result, Date, Title, KBArticle, SupportUrl, Product, UpdateId, RevisionNumber } function Get-UsersToDisable { [CmdletBinding()] param ( [Parameter( ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0 )] [string]$DirPath = "C:\Temp", [Parameter( ValueFromPipelineByPropertyName = $true )] [int]$DaysToExpire = 90, [Parameter( ValueFromPipelineByPropertyName = $true )] [string]$SMTPUsername, [Parameter( ValueFromPipelineByPropertyName = $true )] [string]$SMTPPass ) Begin { Write-Host "Checking for users not active in $DaysToExpire days." -ForegroundColor Yellow Write-Host "Output directory is $DirPath" -ForegroundColor Yellow $DirPathCheck = Test-Path -Path $DirPath If (!($DirPathCheck)) { Try { #If not present then create the dir New-Item -ItemType Directory $DirPath -Force } Catch { Write-Output 'The Directory'$DirPath'was not created.' } } } Process { $Header = @" <style> TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;} TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #6495ED;} TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;} </style> "@ # Paths $csvpath = "$DirPath\$env:USERDOMAIN.ADAudit.$((get-date).ToString('MM-dd-yyyy.hh.mm.ss')).csv" $htmlpath = "$DirPath\$env:USERDOMAIN.ADAudit.$((get-date).ToString('MM-dd-yyyy.hh.mm.ss')).html" # Days inactive $time = (Get-Date).AddDays( - ($DaysToExpire)) Try { # Get inactive enabled users $output = Get-ADUser -Filter { LastLogonTimeStamp -gt $time -and enabled -eq $true } ` -Properties UserPrincipalName, LastLogonTimeStamp, PasswordLastSet, LockedOut, ` CannotChangePassword, LastBadPasswordAttempt, SamAccountName, Title | ` Where-Object { $_.name -ne "krbtgt" } | ` Select-Object Name, SamAccountName, UserPrincipalName, Title, ` PasswordLastSet, LockedOut, LastBadPasswordAttempt, CannotChangePassword, ` @{Name = "LastLogon"; Expression = { [DateTime]::FromFileTime($_.lastLogonTimestamp) } }, ` @{Name = "Confirmed?"; Expression = { "" } } | ` Sort-Object LastLogon -Descending } catch { Write-Output "The users were not able to be retrieved" } try { # Export output to csv without type information $output | Export-CSV -Path $csvpath -NoTypeInformation Write-Host "The path to the CSV is: " -ForegroundColor Green Write-Output $csvpath } catch { Write-Output "The csv was not created" } try { # Export Preformatted Table in HTML $output | ConvertTo-Html -Title "$($env:USERDOMAIN) AD Inactive User Audit" -Head $Header | Out-File -Encoding utf8 $htmlpath Write-Host "The path to the HTML is: " -ForegroundColor Green Write-Output $htmlpath } catch { Write-Output "The html was not created" } } end { <# function Send-ToEmail([string]$email ) { $message = new-object Net.Mail.MailMessage; $message.From = $Username; $message.To.Add($email); $message.Subject = "Active Directory Enabled Users Audit"; $message.Body = "Audit of active enabled users who have not logged on in $DaysToExpire days."; write-host "attaching" $file = $csvpath $att = new-object Net.Mail.Attachment($file) $message.Attachments.Add($file) write-host "new smtp" $smtp = new-object Net.Mail.SmtpClient("smtp.office365.com", "587"); $smtp.EnableSSL = $true; $smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password); write-host "new send" $smtp.send($message); write-host "pre dispose" $att.Dispose() write-host "**Mail Sent" ; } Send-ToEmail -email "recipient@yourdomain.com"; #> } } |