PowerShell Scripting

All posts containing PowerShell-related scripts and patterns.

PowerShell E-mail Function

Met behulp van onderstaande functie kun je vanuit een script een e-mail verzenden. De procedure is in een functie gegoten waardoor deze gemakkelijk kan worden hergebruikt. Deze functie werkt zowel in PowerShell V1 als PowerShell V2. Deze functie maakt gebruik van een andere functie fnWriteEventLog t.b.v. schrijfacties naar het Windows EventLog.

function fnSendMail()
{
  param (
    [string]$sSMTPSrvrName, 
    [string]$sFrom, 
    [string]$sTo, 
    [string]$sSubject, 
    [string]$sBody, 
    [string]$sAttFileName, 
    [switch]$swIsBodyHTML = $false
    )

  if (($sSMTPSrvrName) -and ($sFrom) -and ($sTo) -and $sSubject) {
  
    # Declare mail objects...
    $oMessage = new-object Net.Mail.MailMessage
    $oSMTP = new-object Net.Mail.SmtpClient($sSMTPSrvrName)

    # Pass values to object...
    $oMessage.From = $sFrom
    $oMessage.To.Add($sTo)
    $oMessage.Subject = $sSubject
    $oMessage.IsBodyHtml = $swIsBodyHTML
    $oMessage.BodyEncoding = ([System.Text.Encoding]::UTF8)
    if ($sBody) { $oMessage.Body = $sBody }

    # Add attachment...
    if ($sAttFileName) {
      $oAttachment = new-object Net.Mail.Attachment($sAttFileName)
      $oMessage.Attachments.Add($oAttachment)
    }

    $oSMTP.Send($oMessage)
    if ($? -eq "True") {
      #fnWriteEventLog -sNode (fnGetFQDN) -sMessage "Email has been sent..." -iEventID 1 -sType "Information"
      return "INFO: Email has been sent..." 
    } else {
      fnWriteEventLog -sNode (fnGetFQDN) -sMessage "Error sending mail..." -iEventID 501
      return "ERROR: Error sending e-mail..."
    }

  } else {
    fnWriteEventLog -sNode (fnGetFQDN) -sMessage "fSendMail argument missing..." -iEventID 501
    return "ERROR: Argument(s) missing. [fnSendMail `"SMTPServerName`" `"From`" `"To`" `"Subject`" `"Body`" (`"AttachFileName`" `"isBodyHTML`")]"
  }
}

PowerShell Create MSSQL Agent Job

M.b.v. onderstaande PowerShell script voorbeeld kun je, door gebruik te maken van SQL PowerShell Modules, een SQL Agent Job aanmaken t.b.v. MS SQL Server.

$oSRV=Get-Item SQLSERVER:\SQLSERVERNAAM\INSTANCENAAM

# Maak een SQL Agent Job...
$oJOB=New-Object Microsoft.SqlServer.Management.Smo.Agent.Job
$oJOB.parent=$oSRV.Jobserver
$oJOB.Name="Backup System Database Job"
$oJOB.Create()

# Maak een JobStep t.b.v. backup master database in de nieuwe Job...
$oStep1=New-Object Microsoft.SqlServer.Management.Smo.Agent.JobStep
$oStep1.parent=$oJOB
$oStep1.Name="Master Backup"
$oStep1.SubSystem="TransactSQL"
$oStep1.Command="BACKUP DATABASE [master] TO DISK='X:\Path\To\File.bak'"
$oStep1.OnSuccessAction = "GotoNextStep"
$oStep1.Create()

# Maak een JobStep t.b.v. backup master database in de nieuwe Job...
$oStep2=New-Object Microsoft.SqlServer.Management.Smo.Agent.JobStep
$oStep2.parent=$oJOB
$oStep2.Name="Model Backup"
$oStep2.SubSystem="TransactSQL"
$oStep2.Command="BACKUP DATABASE [model] TO DISK='X:\Path\To\File.bak'"
$oStep2.OnSuccessAction = "GotoNextStep"
$oStep2.Create()

PowerShell Check File LastWriteTime

PowerShell script to start a specific routine when a file is older than two days (LastWriteTime). This specific example writes an error in the application event log.

# *****************************************************************************
# Scriptnaam: CHKMODTIME.PS1
# Geschreven_door: Tim van Kooten Niekerk
# Versie: 2010.10.29.01
# Info: PowerShell script t.b.v. uitvoeren actie als de wijzigingsdatum
# Info: van het opgegeven bestand ouder is dan ingestelde waarde.
# *****************************************************************************

function fGetFileModTime([string]$sFileName) {
  $vFileInfo = get-childitem $sFileName
  return $vFileInfo.lastwritetime 
}

# Opvragen van wijzigingsdatum bestand...
[datetime]$dFileModTime = fGetFileModTime("D:PadNaarBestand.bak")
# Voer een actie uit als de wijzigingsdatum van het bestand ouder is dan 2 dagen...
if ((Get-date).AddDays(-2) -gt $dFileModTime) {
  # Schrijf Error melding weg naar eventlog of voer een andere actie uit...  
  $oEventLog = new-object System.Diagnostics.EventLog('Application')
  $oEventLog.MachineName = "."
  $oEventLog.Source = "WSH"
  $oEventLog.WriteEntry("Back-up is to old...", "Error")
}

 

PowerShell Edit Multiple Files

PowerShell example to edit multiple files. This specific example remove the first 15 chars from every XML file in a directory.

get-childitem D:TEMPMessages *.xml |
  % { 
         [string]$sFileContent = cat $_.fullname
         $sFileContent = $sFileContent.substring(15,$sFileContent.length-15) | Out-File -Filepath $_.fullname
         echo $_.fullname
  }

PowerShell BizTalk WMI

Specific PowerShell script to shutdown a BizTalk receive location when a disk is more then 80% full. This application uses WMI to request disk info and shutdown the the receive location.

function fGetDiskFillPerc([string]$vComputer, [string]$vDiskID) {
  $vCommandLine1 = "Get-WMIObject -ComputerName '" + $vComputer + "' Win32_LogicalDisk -filter `"DeviceID = '" + $vDiskID + "'`""
  $vResult1 = Invoke-Expression $vCommandLine1
  foreach ( $vDisk in $vResult1 ) {
    if ($vDisk.DriveType -eq 3) { 
      [decimal]$dDiskFill = $vDisk.Size - $vDisk.FreeSpace
      return $dDiskFill / $vDisk.Size * 100
    }
  }
}
 [decimal]$dDiskFillPercResult = fGetDiskFillPerc "." "D:"
if ( $dDiskFillPercResult -gt 80 ) {
  $oRecLoc1 = get-wmiobject MSBTS_ReceiveLocation  -namespace 'rootMicrosoftBizTalkServer' -filter "Name='ReceivePortName'"
  [void]$oRecLoc1.Disable()
}

 

Powershell Fail-Back script

Simple script using the cluster command to return a cluster group to a prefered node.

# ********************************************************************
# Scriptnaam: AUTOFAILBACK.PS1
# Geschreven_door: Tim van Kooten Niekerk
# Versie: 20100412
# Info: Failback to preferred node (TST en ACC omgeving) 
# ********************************************************************

# Constanten en andere string waarden...
[string]$sClusterGroupCmd = "cluster group"
[string]$sOutputLOGFile = "AutoFailBack.log"
[string]$sDateTime = Get-Date -f o
$sDateTime + ";START;>>> Start controle en AutoFail-Back procedure..." | Out-File -Filepath $sOutputLOGFile

function fAutoFailBack([string]$sClusterGroup1, [string]$sPreferredNodeCG1) {
  [string]$sDateTime = Get-Date -f o
  [string]$sClusterGroup1Clean = $sClusterGroup1.Replace("", "")
  $vResult1 = Invoke-Expression $sClusterGroupCmd
  $vResult2 = $vResult1 | select-string -Pattern $sClusterGroup1 | select-string -Pattern "Online" | select-string -Pattern $($sPreferredNodeCG1)
  if ($vResult2.LineNumber -gt 0) {
    $vResultFIN = $sDateTime + ";OK;" + $vResult2.Line
	
  } else {
    [string]$sClusterGroupCmdFO =  $sClusterGroupCmd  + " `"" + $($sClusterGroup1Clean) +  "`" `/moveto:" + $($sPreferredNodeCG1)
    $vResultB1 = Invoke-Expression $sClusterGroupCmdFO
    $vResultB2 = $vResultB1 | select-string -Pattern $sClusterGroup1 | select-string -Pattern "Online" | select-string -Pattern $($sPreferredNodeCG1)
    if ($vResultB2.LineNumber -gt 0) { 
      $vResultFIN = $sDateTime + ";FO-OK;" + $vResultB2.Line
    } else {
      $vResultC1 = Invoke-Expression $sClusterGroupCmd
      $vResultC2 = $vResultC1 | select-string -Pattern $sClusterGroup1
      $vResultFIN = $sDateTime + ";FO-FAIL;" + $vResultC2.Line
    }

  }
  # Schrijf resultaat weg naar Logbestand
  $vResultFIN | Out-File -Filepath $sOutputLOGFile -Append
}

fAutoFailBack "CLUSTERGROUPNAME" "NODENAME"
fAutoFailBack "CLUSTERGROUPNAME2" "NODENAME"

 

PowerShell PingProbe script

Onderstaand een een eenvoudig PowerShell script om m.b.v. het PING commandp te controleren of een host nog online. De resultaten worden samen met een datumcode weggeschreven naar een logbestand.

# ********************************************************************
# Scriptnaam: PINGPROBE.PS1
# Geschreven_door: Tim van Kooten Niekerk
# Versie: 200910211650
# Info: Script stuurt een ping naar een gespecificeerd IP-adress en
# Info: schrijft resultaat weg in een gespecificeerd LOG-bestand.
# ********************************************************************

# Constanten en andere string waarden...
[string]$sIPAddress1 = "[IP-ADRESS-OR-HOSTNAME]"
[string]$vOutputTXTFile = "C:PingLog.txt"
[string]$sCommandLine1 = "ping " + $sIPAddress1 + " -n 1 | select-string -Pattern `"Reply`""
[string]$sDateTime = Get-Date -f o

$vResult1 = Invoke-Expression $sCommandLine1
if ($vResult1.LineNumber -gt 0) {
[bool]$bIsPingable = $True
[string]$sComment1 = $vResult1.line
} else {
[bool]$bIsPingable = $False
[string]$sComment1 = "No Reply..."
}

# Stel samen en voer resultaat uit naar bestand...
$sDateTime + ";" + $bIsPingable + ";" + $sComment1 | Out-File -Append -Filepath $vOutputTXTFile

PowerShell batch nslookup

Article is written in the Dutch language… 

Onderstaande PowerShell script zoekt ip-adressen bij hostnamen uit een CSV-bestand en schrijft deze waarden weg in een text-bestand. De eerste regel van het CSV-bestand moet de kolomnamen bevatten. Het script kijkt naar de kolom met de naam “Hostname”.

# *****************************************************************************
# Scriptnaam: NSLOOKUP2.PS1
# Geschreven_door: Tim van Kooten Niekerk
# Versie: 2009.10.16.01
# Info: Dit script zoekt IP-adressen bij hostnamen vanuit een CSV-bestand.
# Info: De resultaten worden uitgevoerd naar bestand: "IPadressen.txt".
# Info: De 1e regel van het CSV-bestand moet kolomnamen bevatten. 
# INfo: Het script kijkt alleen naar de kolom "Hostname".
# *****************************************************************************

$vDNSServerIP = "[server-ip-address]"
$vImportCSVFile = "HostNames.csv"
$vOutputTXTFile = "IPadressen.txt"

$aImportCSV1 = import-csv $vImportCSVFile
foreach ($vRow in $aImportCSV1 ) { 
  $vNSLookup = nslookup $($vRow.Hostname) $($vDNSServerIP) | `
               select-string -NotMatch -Pattern $($VDNSServerIP)
  $VNSLookupIP = $vNSLookup | select-string -Pattern "Address"
  $VNSLookupName = $vNSLookup | select-string -Pattern "Name"

  # Stel een regel samen t.b.v. uitvoer bestand...
  "Question:   " + $vRow.HostName + "	" + `
  $vNSLookupName.Line + "	" + `
  $vNSLookupIP.Line | `
  Out-File -Append -Filepath $vOutputTXTFile
}

 

PowerShell AD groupmembers

Simple script using dsquery to query groupmembers from an Active Directory group and return the results to screen. The script takes parameters from the commandline (groupmem.ps1 “DOMAIN” “GROUP_NAME”).

[string]$sADPath = dsquery group -domain "$($args[0])" -name "$($args[1])"
$sADPath = "LDAP://" + $sADPath | Foreach-Object {$_ -replace "`"", ""}
$oADGroup = [ADSI]("$sADPath")
$oADGroup.path
$oADGroup.member