Sunday, April 24, 2011

The 2011 Scripting Games Advanced Event 2: Use PowerShell to Identify Status of Service Dependencies

The 2011 Scripting Games Advanced Event 2: Use PowerShell to Identify Status of Service Dependencies

My personal script:
http://2011sg.poshcode.org/804
Average Rating: 3.50 by 3 users.
(Download it)


#
#
# 2011 Scripting Games Advanced Event 2: Use PowerShell to Identify Status of Service Dependencies
#
# by F.Richard 2011-04
#
#

#Requires -Version 2.0

# Main Program
Param(
[parameter(Position=0)]
[String[]]
$action,
[parameter(Position=1)]
[String[]]
$inputfile
)




# ***********************************************

Function isComputerInADomain {
<#
.SYNOPSIS
Is computer in a domain
.DESCRIPTION
Is computer in a domain. Return $True or $False
.PARAMETER strComputer
Computer name. Default to localhost.
.EXAMPLE
isComputerInADomain
is local machine in a domain ?
.EXAMPLE
isComputerInADomain mycomputer
is mycomputer in a domain ?
#>
Param ([string] $strComputer)
$strComputer = $(if ($strComputer) {$strComputer} else {Get-Content ENV:COMPUTERNAME})
if ((Get-WmiObject -ComputerName $strComputer Win32_ComputerSystem).PartOfDomain -eq $true) {
return $true
} else {
return $false
}
}

# ***********************************************

Function GetUserDomainDNS {
<#
.SYNOPSIS
return user domain name in DNS format ex: domain.net
.DESCRIPTION
return user domain name in DNS format ex: domain.net
.EXAMPLE
GetUserDomainDNS
return user domain name ex: domain.net
#>
[string] $strDomainDNS = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name
Return $strDomainDNS
}

# ***********************************************

Function GetComputerDomainDNS {
<#
.SYNOPSIS
return local computer domain name in DNS format ex: domain.net
.DESCRIPTION
return local computer domain name in DNS format ex: domain.net
.EXAMPLE
GetComputerDomainDNS
return local computer domain name ex: domain.net
#>
[string] $strDomainDNS = [System.DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain().Name
Return $strDomainDNS
}

# ***********************************************

# GetDomainDN
# get Domain name in DNS format ex: domain.net
#
Function GetDomainDN {
<#
.SYNOPSIS
return domain name in Distinguished Name format ex: DC=DOMAIN,DC=NET
.DESCRIPTION
from domain name DNS format domain.net to
return domain name in Distinguished Name format ex: DC=DOMAIN,DC=NET
.PARAMETER strDomainDNS
Domain name in DNS format. Ex: domain.net
.EXAMPLE
GetDomainDN domain.net
return DC=DOMAIN,DC=NET
.EXAMPLE
GetDomainDN -strDomainDNS domain.net
return DC=DOMAIN,DC=NET
#>
Param ([string] $strDomainDNS)
$strDomainDN = "DC=" + $strDomainDNS -replace "\.",",DC="
Return $strDomainDN
}

# ***********************************************

Function SearchAD {
<#
.SYNOPSIS
return AD query
.DESCRIPTION
return AD query
.PARAMETER options
Hashtable
.EXAMPLE
$hashSearchAD = @{ }
$hashSearchAD["strFilter"] = "(objectCategory=computer)"
$hashSearchAD["strSearchScope"] = "Subtree"
$hashSearchAD["colAttributes"] = "name"
$hashSearchAD["strBaseDN"] = "DC=DOMAIN,DC=NET"
searchAD $hashSearchAD
#>
Param ([hashtable] $options)
$strFilter = $(if ($options.ContainsKey("strFilter")) {$options["strFilter"]} else {""}) # ex: '(objectCategory=computer)'
$strSearchScope = $(if ($options.ContainsKey("strSearchScope")) {$options["strSearchScope"]} else {"Subtree"}) # Base, OneLevel or Subtree
$colAttributes = $(if ($options.ContainsKey("colAttributes")) {$options["colAttributes"]} else {""}) # ex: '"name", "jobTitle", "telephoneNumber"
$strBaseDN = $(if ($options.ContainsKey("strBaseDN")) {$options["strBaseDN"]} else {""}) # ex: DC=Domain,DC=NET

$strBase = New-Object System.DirectoryServices.DirectoryEntry ("LDAP://" + $strBaseDN)
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $strBase
$objSearcher.PageSize = 1000
$objSearcher.Filter = $strFilter
$objSearcher.SearchScope = $strSearchScope
Foreach ($attribute in $colAttributes){$objSearcher.PropertiesToLoad.Add($attribute)}

$dtResult = New-Object "System.Data.DataTable"
$dtResult = $objSearcher.FindAll() # .FindOne() .FindAll()
#Write-host "count:" $dtResult.count
return $dtResult
}

# ***********************************************

Function TestFile {
<#
.SYNOPSIS
Test if file exist
.DESCRIPTION
Test if file strFilename exist
Then test if file exist in strCurDir\strFilename path
Return filename path
.PARAMETER strFilename
filename to test
.PARAMETER strCurDir
directory to test filename if not in current directory
.EXAMPLE
TestFile -strFilename abcdefghijkl.txt
return
ERROR: file abcdefghijkl.txt NOT exist
ERROR: file D:\Datas\Dev\abcdefghijkl.txt NOT exist
.EXAMPLE
TestFile -strFilename regedit.exe -strCurDir C:\WINDOWS
return C:\WINDOWS\regedit.exe
#>
Param(
[String] $strFilename,
[String] $strCurDir
)
if ($strFilename) {
$strCurDir = $(if ($strCurDir) {$strCurDir} else {if ($MyInvocation.MyCommand.CommandType -eq "Function") {(Get-Location).Path} else {Split-Path -parent $MyInvocation.MyCommand.Path} })
If ((Test-Path("$strFilename")) -eq $False){
If ($strFilename.ToUpper().Contains($strCurDir.ToUpper()) ) {
Write-Host "ERROR: file $strFilename NOT exist"
return
} Else {
If ((Test-Path("$strCurDir\$strFilename")) -eq $False){
Write-Host "ERROR: file $strFilename NOT exist"
Write-Host "ERROR: file $strCurDir\$strFilename NOT exist"
return
} Else {
$strFilename = "$strCurDir\$strFilename"
}
}
}
return $strFilename
}
}


# ***********************************************

Function GetFileIntoArr {
<#
.SYNOPSIS
Import File into an array
.DESCRIPTION
Import File into an array
.PARAMETER strFilename
filename to import
.PARAMETER strCurDir
directory to test filename if not in current directory
.PARAMETER arrFile
array where file is imported
.PARAMETER strComment
1st line character for comment line (default: #)
.EXAMPLE
[Array] $arrContent = @( )
GetFileIntoArr -strFilename .\content.txt -arrFile ([Ref]$arrContent)
return
#>
Param(
[String] $strFilename,
[String] $strCurDir,
[Ref]$arrFile,
[String] $strComment
)
$strComment = $(if ($strComment) {$strComment} else {"#"})
$strCurDir = $(if ($strCurDir) {$strCurDir} else {if ($MyInvocation.MyCommand.CommandType -eq "Function") {(Get-Location).Path} else {Split-Path -parent $MyInvocation.MyCommand.Path} })

$retFilename = TestFile -strFilename $strFilename -strCurDir $strCurDir
if ($retFilename) {
$Content = Get-Content "$retFilename"
Foreach ($line in $Content) {
$comment = $False
If ($line.Trim().length -gt 0) { # take only line with data and without # at begininng of the line
# if we do not want to use comment
If ($strComment -eq "#") {
If ($line.substring(0,1) -eq "#") {
$comment = $True
}
}
If ($comment -eq $False) {
# Get Search & Replace
$arrFile.Value += $line.Trim()
}
}
}
return $True
} else {
return $False
}
}

# ***********************************************

Function GetXlsIntoArr {
<#
.SYNOPSIS
Import Excel file into an array
.DESCRIPTION
Import Excel file into an array
.PARAMETER strFilename
filename to import
.PARAMETER strSheet
sheet to open
.PARAMETER arrFile
array where file is imported
.PARAMETER strComment
1st line character for comment line (default: #)
.EXAMPLE
[Array] $arrContent = @( )
GetFileIntoArr -strFilename .\content.txt -arrFile ([Ref]$arrContent)
return
#>
Param(
[String] $strFilename,
[String] $strCurDir,
[String] $strSheet,
[Int] $iColumn,
[Ref]$arrFile
)
$strComment = $(if ($strComment) {$strComment} else {"#"})
$strCurDir = $(if ($strCurDir) {$strCurDir} else {if ($MyInvocation.MyCommand.CommandType -eq "Function") {(Get-Location).Path} else {Split-Path -parent $MyInvocation.MyCommand.Path} })
$strSheet = $(if ($strSheet) {$strSheet} else {""})
$iColumn = $(if ($iColumn) {$iColumn} else {1})
$retFilename = TestFile -strFilename $strFilename -strCurDir $strCurDir
if ($retFilename) {
$objExcel=New-Object -ComObject Excel.Application
$objExcel.Visible=$false
if ($retFilename.substring(0,2) -eq ".\") { $retFilename = (Get-Location).Path + $retFilename.substring(1, $retFilename.length - 1) }
$objWorkbook=$objExcel.Workbooks.Open($retFilename)
if ($strSheet -eq "") {
$strSheet = $objWorkbook.ActiveSheet.Name
}
$objSheet = $objWorkbook.sheets.item($strSheet)
for ($iRow = 1 ; $iRow -le ($objSheet.UsedRange.Rows).count; $iRow++) {
$arrFile.Value += $objSheet.cells.item($iRow,$iColumn).value2
}
$objexcel.quit()
return $True
} else {
return $False
}
}

# ***********************************************

Function GetADComputerToArray {
<#
.SYNOPSIS
return AD Computer query to array
.DESCRIPTION
return AD Computer query to array
.PARAMETER strDomainDN
Domain name in DN format. Default: Computer Domain Name ex: DC=DOMAIN,DC=NET
.PARAMETER strFilter
Computer AD filter. Default: (objectCategory=computer)
.PARAMETER strSearchScope
Domain name in DNS format. Default: Subtree
.PARAMETER colAttributes
Attributes to get. Default: name
.EXAMPLE
[Array] $arrComputers = @( )
GetADComputerToArray -array ([Ref]$arrComputers)
#>
Param(
[Ref]$array,
[String] $strDomainDN,
[String] $strFilter,
[String] $strSearchScope,
[String] $colAttributes
)
$strDomainDN = $(if ($strDomainDN) {$strDomainDN} else {GetDomainDN -strDomainDNS (GetComputerDomainDNS)})
$strFilter = $(if ($strFilter) {$strFilter} else {'(objectCategory=computer)'})
$strSearchScope = $(if ($strSearchScope) {$strSearchScope} else {"Subtree"})
$colAttributes = $(if ($colAttributes) {$colAttributes} else {"name"})
$hashSearchAD = @{ }
$hashSearchAD["strFilter"] = $strFilter
$hashSearchAD["strSearchScope"] = $strSearchScope # Base, OneLevel or Subtree
$hashSearchAD["colAttributes"] = $colAttributes # ex: '"name", "jobTitle", "telephoneNumber"
$hashSearchAD["strBaseDN"] = $strDomainDN
$dtResult = SearchAD($hashSearchAD)
If ($dtResult -ne $Null) {
Foreach ($row in $dtResult){
If ($row.GetType().Name -eq "Int32") {
} else {
$result = $row.GetDirectoryEntry()
$array.Value += $result.Name
Write-Host $result.Name
}
}
}
}

# ***********************************************



Function Get-AdvEvent2 {
<#
.SYNOPSIS
2011 Scripting Games Advanced Event 2
.DESCRIPTION
2011 Scripting Games Advanced Event 2
Use PowerShell to Identify Status of Service Dependencies
.PARAMETER action
action : ad / file / localhost
.PARAMETER inputfile
inputfile filename for file option
.EXAMPLE
Get-AdvEvent2 ad
Get process module version for AD query computers
.EXAMPLE
Get-AdvEvent2 file filename.txt
Get process module version for all computers in filename.txt
.EXAMPLE
Get-AdvEvent2 excel filename.xls
Get process module version for all computers in excel file filename.xls
#>
Param(
[String] $action,
[String] $inputfile
)
# local computername
$computername = (Get-Content ENV:COMPUTERNAME)
[Array] $arrComputers = @( )

# Default action = localhost
switch($action) {
# AD Query
"ad" {
if(isComputerInADomain) {
# AD query but only Servers
GetADComputerToArray -array ([Ref]$arrComputers) -strFilter "(&(objectcategory=computer)(|(operatingsystem=Windows 2000 Server)(operatingsystem=Windows Server*))) "
} else {
Write-Host "ERROR: $computername is NOT in a domain. You cound not use switch $action"
return
}
}

# File content
"file" {
if ($inputfile) {
if (!(GetFileIntoArr -strFilename $inputfile -arrFile ([Ref]$arrComputers))) {
return
}
} else {
Write-Host "ERROR: With action $action switch you need a filename.txt as second parameter inputfile"
return
}
}

# File content
"excel" {
if ($inputfile) {
if (!(GetXlsIntoArr -strFilename $inputfile -arrFile ([Ref]$arrComputers))) {
return
}
} else {
Write-Host "ERROR: With action $action switch you need a filename.xls as second parameter inputfile"
return
}
}

# Others actions = Help
Default {
get-help Get-AdvEvent2 -full
return
}
}


#$ErrorActionPreference = Continue
$string=""
Foreach ($computer in $arrComputers) {
# Test if computer is a Server
$win32os = $null
$win32os = Get-WmiObject -ComputerName $computer Win32_OperatingSystem
if ( ($win32os -ne $null) -and ($win32os.ProductType -ne 1)) {
Write-Output $string.PadRight(80,"-")
Write-Output "Computername: $computer"
# Get all services running
$services = Get-Service -Computername $computer | Where-Object { $_.Status -eq "Running" }
Foreach ($service in $services) {
Write-Output $service.Name
Write-Output $string.PadRight($service.Name.Length,"-")
# Get all Dependent services
$service.DependentServices | Select-Object -Property name, status | Format-Table -HideTableHeaders
Write-Output "`r`n"
}
}

}

}


# ***********************************************

# Main program

Get-AdvEvent2 -action $action -inputfile $inputfile

No comments: