powershell

List Security group members with a autocomplete form

 

#http://social.technet.microsoft.com/wiki/contents/articles/28824.how-to-add-a-graphical-user-interface-to-your-powershell-functions-using-the-net-systemwindowsform-class.aspx
#https://community.spiceworks.com/topic/255740-powershell-script-to-show-all-groups-in-ad
#https://www.petri.com/powershell-problem-solver-exporting-active-directory-groups-csv
get-adgroup -filter 'GroupCategory -eq "Security"'  | sort name | select Name|Export-Csv -Path $env:temp\ADGroup.txt -NoTypeInformation
(Get-Content $env:temp\ADGroup.txt) -replace '"''' | Set-Content $env:temp\ADGroup.txt
Import-Module activedirectory
#import Presentation framework for error message pop-up
Add-Type -AssemblyName PresentationCore,PresentationFramework
Function getADMember($groupName)
{
    try
    {
        Get-ADGroupMember $groupName -Recursive|select-object name,SamAccountName,distinguishedName,objectClass|Export-Csv -Path $env:temp\$groupName.csv -NoTypeInformation
        #|Export-Csv -Path $env:temp\$groupName.csv -NoTypeInformation
        #Out-GridView -PassThru|
        invoke-item -Path $env:temp\$groupName.csv
    }
    catch
    {
        $ButtonType = [System.Windows.MessageBoxButton]::OK
        $MessageIcon = [System.Windows.MessageBoxImage]::Error
        $MessageBody = $($_.Exception.Message)
        $MessageTitle "Error"
        $Result = [System.Windows.MessageBox]::Show($MessageBody,$MessageTitle,$ButtonType,$MessageIcon)
    }
    finally
    {
        
    }
}
#region Boring beginning stuff
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
#endregion
  
#region begin to draw forms
$Form = New-Object System.Windows.Forms.Form
$Form.Text = "Get AD Group Member"
$Form.Size = New-Object System.Drawing.Size(300,170)
$Form.StartPosition = "CenterScreen"
$Form.KeyPreview = $True
$Form.MaximumSize = $Form.Size
$Form.MinimumSize = $Form.Size
  
$label = New-Object System.Windows.Forms.label
$label.Location = New-Object System.Drawing.Size(5,5)
$label.Size = New-Object System.Drawing.Size(240,30)
$label.Text = "Type any group name"
$Form.Controls.Add($label)
$textbox = New-Object System.Windows.Forms.TextBox
$textbox.Location = New-Object System.Drawing.Size(5,40)
$textbox.Size = New-Object System.Drawing.Size(165,25)
#$textbox.Text = "Select source PC:"
$Form.Controls.Add($textbox)
  
$search_group =
{
#region Actual Code
  
$statusBar1.Text = "Searching..."
$DLName $textbox.Text
  
getADMember($DLName)
  
$statusBar1.Text = "Searching Complete"
#endregion
}
  
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(180,38)
$OKButton.Size = New-Object System.Drawing.Size(50,23)
$OKButton.Text = "OK"
$OKButton.Add_Click($search_group)
$Form.Controls.Add($OKButton)
  
$result_label = New-Object System.Windows.Forms.label
$result_label.Location = New-Object System.Drawing.Size(5,65)
$result_label.Size = New-Object System.Drawing.Size(240,30)
$result_label.Text = ""
$Form.Controls.Add($result_label)
  
$statusBar1 = New-Object System.Windows.Forms.StatusBar
$statusBar1.Name = "statusBar1"
$statusBar1.Text = "Ready..."
$form.Controls.Add($statusBar1)
  
$Form.Add_KeyDown({if ($_.KeyCode -eq "Enter"){& $search_group}})
$Form.Add_KeyDown({if ($_.KeyCode -eq "Escape")
{$Form.Close()}})
#endregion begin to draw forms
#Autocomplete region begins here
$textbox.AutoCompleteSource = 'CustomSource'
$textbox.AutoCompleteMode='SuggestAppend'
$textbox.AutoCompleteCustomSource=$autocomplete
#Importing from a file
Get-content -Path $env:temp\ADGroup.txt | % {$textbox.AutoCompleteCustomSource.AddRange($_) }
#Autocomplete region ends here
  
#Show form
$Form.Topmost = $True
$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()

Creating a form with .NET library in PowerShell

Below is an example of calling .NET library with PowerShell to build a form. The form will have a textbox for user to input a computer name to ping.

Web link reference included in the comment

#http://social.technet.microsoft.com/wiki/contents/articles/28824.how-to-add-a-graphical-user-interface-to-your-powershell-functions-using-the-net-systemwindowsform-class.aspx
#region Boring beginning stuff
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
#endregion
  
#region begin to draw forms
$Form = New-Object System.Windows.Forms.Form
$Form.Text = "Computer Pinging Tool"
$Form.Size = New-Object System.Drawing.Size(300,170)
$Form.StartPosition = "CenterScreen"
$Form.KeyPreview = $True
$Form.MaximumSize = $Form.Size
$Form.MinimumSize = $Form.Size
  
$label = New-Object System.Windows.Forms.label
$label.Location = New-Object System.Drawing.Size(5,5)
$label.Size = New-Object System.Drawing.Size(240,30)
$label.Text = "Type any computer name to test if it is on the network and can respond to ping"
$Form.Controls.Add($label)
$textbox = New-Object System.Windows.Forms.TextBox
$textbox.Location = New-Object System.Drawing.Size(5,40)
$textbox.Size = New-Object System.Drawing.Size(120,20)
#$textbox.Text = "Select source PC:"
$Form.Controls.Add($textbox)
  
$ping_computer_click =
{
#region Actual Code
  
$statusBar1.Text = "Pinging..."
$ComputerName $textbox.Text
  
if (Test-Connection $ComputerName -quiet -Count 2){
Write-Host -ForegroundColor Green "Computer $ComputerName has network connection"
$result_label.ForeColor= "Green"
$result_label.Text = "System Successfully Pinged"
}
Else{
Write-Host -ForegroundColor Red "Computer $ComputerName does not have network connection"
$result_label.ForeColor= "Red"
$result_label.Text = "System is NOT Pingable"
}
  
$statusBar1.Text = "Testing Complete"
#endregion
}
  
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(140,38)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click($ping_computer_click)
$Form.Controls.Add($OKButton)
  
$result_label = New-Object System.Windows.Forms.label
$result_label.Location = New-Object System.Drawing.Size(5,65)
$result_label.Size = New-Object System.Drawing.Size(240,30)
$result_label.Text = "Results will be listed here"
$Form.Controls.Add($result_label)
  
$statusBar1 = New-Object System.Windows.Forms.StatusBar
$statusBar1.Name = "statusBar1"
$statusBar1.Text = "Ready..."
$form.Controls.Add($statusBar1)
  
$Form.Add_KeyDown({if ($_.KeyCode -eq "Enter"){& $ping_computer_click}})
$Form.Add_KeyDown({if ($_.KeyCode -eq "Escape")
{$Form.Close()}})
#endregion begin to draw forms
  
#Show form
$Form.Topmost = $True
$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()

[PowerShell] Send email from Gmail with attachment on PowerShell

Credits goes to 

I modified the script a little bit to pick up the log from c:\temp\ daily where the filename is made up of yyyymmdd

$a = Get-Date -Format yyyyMMdd

$smtpClient = new-object system.net.mail.smtpClient 
$smtpClient.Host = 'smtp.gmail.com'
$smtpClient.Port = 587
$smtpClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("username@gmail.com", "password");

$emailFrom = "sender@domain.com"
$emailTo = "receipt1@domain.com,receipt2@domain.com"
$Subject = "Backup log for " +$a
$Body = "Please refer to attached logfile."

$emailMessage = New-Object System.Net.Mail.MailMessage
$emailMessage.From = $EmailFrom
$emailMessage.To.Add($EmailTo)
$emailMessage.Subject = $Subject
$emailMessage.Body = $Body
$emailMessage.Attachments.Add("C:\temp\libra_backup"+ $a+".txt")
$SMTPClient.Send($emailMessage)
$emailMessage.Attachments.Dispose()

 

For more information on Get-Date format, please click here

[PowerShell] Retrieving hard disk health through SMART status

To get the SMART status of the hard disk with PowerShell, you could run the following:

Get-WmiObject win32_diskdrive|Select-Object Status

 

Below is a sample script to check multiple PC’s SMART status by getting a list of PC names from a text file.

$allComputers=Get-Content -Path C:\temp\pc.txt

foreach($computer in $allComputers)
{

$isonline=test-connection -Quiet -count 2 -ComputerName $computer
if($isonline)
{

$diskStatus= Get-WmiObject win32_diskdrive -ComputerName $computer|Select-Object -ExpandProperty Status

Write-Host -ForegroundColor Green "$computer is online and disk status is $diskStatus";
$diskStatus="";
}
else
{
Write-Host -ForegroundColor Red "$computer is offline";
}

}

[PowerShell] Script Lets You Check Patches’ Status

I was asked to modify the script posted at http://windowsitpro.com/scripting/powershell-script-lets-you-check-patches-status

such that given a list of computers, check if any PC has missed a KB. So here it is:

$erroractionpreference = “SilentlyContinue”
clear-host

if ($args.count -lt 2)
{
write-host -f blue “Syntax Error : Must have 2 parameters.”
write-host -f blue “Eg powershell.exe \kb.ps1 ”
break
}

$filename = $args[0]
$computer = $args[1]
$kbs = get-content $filename
$kbTotal = 0
$kbNotFound = 0
write-host -f green “Checking on”$computer

foreach ($kb in $kbs)
{
$global:kbTotal++
$strQuery = “select * from win32_pingstatus where address = ‘” + $computer + “‘”
$wmi = get-wmiobject -query $strQuery
if ($wmi.statuscode -eq 0)
{
$checkkb = get-wmiobject Win32_QuickFixEngineering -computer $computer | where-object {$_.hotfixid -eq $kb} | select-object hotfixid, description
# BEGIN CALLOUT A

if ($checkkb.hotfixid -eq $kb)
{write-host -f green $kb “`t” $checkkb.description “`r”}
else
{write-host -f red $kb “`t” “Patch not found.” “`r”
$global:kbNotFound++
}
}
else
{write-host $computer “`t” “Ping failed.” “`r”}
# END CALLOUT A
}

if ($global:kbNotFound -eq 0)
{write-host -ForegroundColor Green $global:kbNotFound “KBs missing out of”$global:kbTotal “required”}
else
{write-host -ForegroundColor Red $global:kbNotFound “KBs missing out of”$global:kbTotal “required”}

Below is the the version where it outputs to a text file, I had modified it to output to c:\temp instead:

# Function : to check for kbxxxx patches on remote pc
# This version redirects the output to a text file.

$erroractionpreference = “SilentlyContinue”

cls
if ($args.count -ne 2)
{
write-host -f blue “Syntax Error : Must have 2 parameters.”
write-host -f blue “Eg powershell.exe \kb.ps1 ”
break
}

$filename = $args[0]
$computer = $args[1]
$kbs = get-content $filename

write-host -f green “Checking on”$computer
“Checking on” +$computer | out-file c:\temp\results.txt -append

foreach ($kb in $kbs)
{

$strQuery = “select * from win32_pingstatus where address = ‘” + $computer + “‘”
$wmi = gwmi -query $strQuery

if ($wmi.statuscode -eq 0)
{
$checkkb = gwmi Win32_QuickFixEngineering -computer $computer | where {$_.hotfixid -eq $kb} | `
select-object hotfixid, description

if ($checkkb.hotfixid -eq $kb)
{
write-host -f green $kb “`t” $checkkb.description “`r”
$kb + ” ” + $checkkb.description | out-file c:\temp\results.txt -append
}

else
{
write-host -f red $kb “`t” “Patch not found.” “`r”
$kb + ” patch not found” | out-file c:\temp\results.txt -append
}

}
else
{
write-host $computer “`t” “Ping fail.” “`r”
$computer + ” ping fail”| out-file c:\temp\results.txt -append
}

}