How to avoid unnecessary output from [System.Net.Dns]::GetHostAddresses("$server_name") - powershell

$inventory = Import-Csv "E:\MonitoringScripts\HealthCheck\PatStat_Pshell\inventory.csv"
foreach ($line in $inventory) {
$server_name = $($line.servername)
$port_number = $($line.port)
$resolved_true = [System.Net.Dns]::GetHostAddresses("$server_name")
#Write-Host $resolved_true
if ($resolved_true) {
#Write-Host $server_name
Write-Host 'the host is resolving'
} else {
Write-Host 'Not found in DNS'
}
}
In the above code, how do I avoid the below content to appear in the command promt when there is a host in the inventory file which is not resolving the dns?
Exception calling "GetHostAddresses" with "1" argument(s): "No such host is
known"
At E:\MonitoringScripts\HealthCheck\PatStat_Pshell\patrol.ps1:9 char:2
+ $resolved_true = [System.Net.Dns]::GetHostAddresses("$server_name")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SocketException
Not found in DNS
the host is resolving
I just want to see:
Not found in DNS
or
the host is resolving

Catch the exception:
try {
[Net.Dns]::GetHostAddresses($server_name)
Write-Host 'the host is resolving'
} catch {
Write-Host 'Not found in DNS'
}

Read About Try Catch Finally:
Use Try, Catch, and Finally blocks to respond to or handle terminating
errors in scripts.
You can apply it as follows:
try {
$resolved_true = [System.Net.Dns]::GetHostAddresses($server_name)
} catch {
$resolved_true = $null
}

Test-Connection to see if the host exists first. Of course, the host existing is not exactly the same thing as finding it in DNS.
$inventory = import-csv “E:\MonitoringScripts\HealthCheck\PatStat_Pshell\inventory.csv”
ForEach ($line in $inventory)
{
$server_name = $($line.servername)
$port_number = $($line.port)
$resolved_true = $null
if (Test-Connection -ComputerName $server_name -ErrorAction SilentlyContinue) {
$resolved_true = [System.Net.Dns]::GetHostAddresses("$server_name")
}
#Write-host $resolved_true
if($resolved_true) {
#write-host $server_name
Write-Host 'the host is resolving'
} else {
Write-Host 'Not found in DNS'
}
}

$inventory = import-csv “E:\MonitoringScripts\HealthCheck\PatStat_Pshell\inventory.csv”
ForEach ($line in $inventory)
{
$server_name = $($line.servername)
$port_number = $($line.port)
$resolved_true = $null
try {
$resolved_true = [System.Net.Dns]::GetHostAddresses($server_name)
} catch {
$resolved_true = $null
}
#Write-host $resolved_true
if($resolved_true) {
#write-host $server_name
Write-Host 'the host is resolving'
} else {
Write-Host 'Not found in DNS'
}
}
This worked for me, Thank you so much all for the help.
I will have to mark #JosefZ Answer, But really thank you all.

Related

Powershell - manage error when registry key not exist

I hope you're well.
Desciption
I requiere your help regarding the following code I use and who can generate an error when registry key do not exist.
In this example:
If the key Ins_ProductVersion exist in both registry path, the code show information expected.
However, if this key do not exist, I got an error exception + the text: - Product Version: Not found!
My goal , is to only get my message and not the error exception
I was thinking that -ErrorAction SilentlyContinue will manage this situation, but not in my case it not seems
foreach ($path in 'HKLM:HKEY_LOCAL_MACHINE\SOFTWARE\xxx\xxxx\xxxx\environment\', 'HKLM:HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\xxx\xxxx\xxxx\environment\') {
$hotfix = Get-ItemPropertyValue -Path $path -Name 'Ins_ProductVersion' -ErrorAction SilentlyContinue
# assuming you want to exit the loop at the first successfull 'hit'
if ($hotfix) { break }
}
if ($hotfix) {
write-host "- Product Version: $hotfix"
}
else {
write-host "- Product Version: Not found!"
}
Thanks for your helps and futur advices.
Regards,
Florian
-------------- new code version ---------------
Not working for now
Original key is : Version
Change this key like : Version1
Output can be found here :
code used
foreach ($path in 'HKLM:\SOFTWARE\Dropbox\Client', 'HKLM:\SOFTWARE\WOW6432Node\Dropbox\Client') {
$hotfix = Get-ItemPropertyValue -Path $path -Name 'Version' -ErrorAction SilentlyContinue
# assuming you want to exit the loop at the first successfull 'hit'
if ($hotfix) { break }
}
if ($hotfix) {
write-host "- Product version: $hotfix"
}
else {
Write-Host "- Product version : Not found"
}
========== SOLUTION ==========
Thanks for your help
foreach ($path in 'HKLM:\SOFTWARE\Dropbox\Client', 'HKLM:\SOFTWARE\WOW6432Node\Dropbox\Client') {
try {
$hotfix = Get-ItemPropertyValue -Path $path -Name 'Version' -ErrorAction Stop
# assuming you want to exit the loop at the first successfull 'hit'
if ($hotfix) { break }
}
catch {
Write-Warning $_.Exception.Message
}
}
if ($hotfix) {
write-host "- Product version: $hotfix"
}
else {
Write-Host "- Product version : Not found"
}
The reason you receive both an exception and your own message is because you have defined the registry paths wrong:
HKLM:HKEY_LOCAL_MACHINE\SOFTWARE\xxx\xxxx\xxxx\environment should be either
HKLM:\SOFTWARE\xxx\xxxx\xxxx\environment OR
Registry::HKEY_LOCAL_MACHINE\SOFTWARE\xxx\xxxx\xxxx\environment
In your code, you have now added the registry hive twice, where you only need the short OR long version here.
This works:
foreach ($path in 'HKLM:\SOFTWARE\xxx\xxxx\xxxx\environment\', 'HKLM:\SOFTWARE\WOW6432Node\xxx\xxxx\xxxx\environment\') {
$hotfix = Get-ItemPropertyValue -Path $path -Name 'Ins_ProductVersion' -ErrorAction SilentlyContinue
# assuming you want to exit the loop at the first successfull 'hit'
if ($hotfix) { break }
}
if ($hotfix) {
write-host "- Product Version: $hotfix"
}
else {
write-host "- Product Version: Not found!"
}
and so does this:
foreach ($path in 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\xxx\xxxx\xxxx\environment\', 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\xxx\xxxx\xxxx\environment\') {
$hotfix = Get-ItemPropertyValue -Path $path -Name 'Ins_ProductVersion' -ErrorAction SilentlyContinue
# assuming you want to exit the loop at the first successfull 'hit'
if ($hotfix) { break }
}
if ($hotfix) {
write-host "- Product Version: $hotfix"
}
else {
write-host "- Product Version: Not found!"
}
without the need to wrap it inside a try{..} catch{..}
Although I do not have any exception messages, and for me the -ErrorAction SilentlyContinue does exactly what is expected, you say you keep also receiving system Exception messages using the above..
In that case, you will need to add a try{..}catch{..} to figure out what exactly errors out like this:
foreach ($path in 'HKLM:\SOFTWARE\Dropbox\Client', 'HKLM:\SOFTWARE\WOW6432Node\Dropbox\Client') {
try {
$hotfix = Get-ItemPropertyValue -Path $path -Name 'Version' -ErrorAction Stop
# assuming you want to exit the loop at the first successfull 'hit'
if ($hotfix) { break }
}
catch {
Write-Warning $_.Exception.Message
}
}
if ($hotfix) {
write-host "- Product version: $hotfix"
}
else {
Write-Host "- Product version : Not found"
}
Now, exceptions will be written to the screen too like
WARNING: Cannot find path 'HKLM:\SOFTWARE\Dropbox\Client' because it does not exist.
WARNING: Cannot find path 'HKLM:\SOFTWARE\WOW6432Node\Dropbox\Client' because it does not exist.
- Product version : Not found
or
WARNING: Property Version does not exist at path HKEY_LOCAL_MACHINE\SOFTWARE\Dropbox\Client.
WARNING: Cannot find path 'HKLM:\SOFTWARE\WOW6432Node\Dropbox\Client' because it does not exist.
- Product version : Not found
Usually best to use error handling properly rather than try to disable it:
$Paths = 'HKLM:HKEY_LOCAL_MACHINE\SOFTWARE\xxx\xxxx\xxxx\environment\', 'HKLM:HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\xxx\xxxx\xxxx\environment\'
$Paths | ForEach-Object {
Try {
$CurPath = $_
$hotfix = Get-ItemPropertyValue -Path $CurPath -Name 'Ins_ProductVersion' -ErrorAction Stop
}
Catch {
$RegError = "Error obtaining reg key: $_"
}
If ($hotfix) {
[pscustomobject]#{RegPath=$_;Hotfix=$hotfix}
}
Else {
[pscustomobject]#{RegPath=$_;Hotfix=$RegError}
}
}
Or:
$Paths | ForEach-Object {
Try {
$CurPath = $_
$hotfix = Get-ItemPropertyValue -Path $CurPath -Name 'Ins_ProductVersion' -ErrorAction Stop
[pscustomobject]#{RegPath=$_;Hotfix=$hotfix}
}
Catch {
$RegError = "Error obtaining reg key: $_"
[pscustomobject]#{RegPath=$_;Hotfix=$RegError}
}
}

You cannot call a method on a null-valued expression

Not having much luck with my Powershell script, so any help would be great! What I'm trying to do is to reference from a test file that contains lines of usernames, and compare it to the Excel spreadsheet on column A1. If exists, it should blank out the username.
$users = Get-Content "E:\temp\test.txt"
foreach ($user in $users) {
set-aduser $user -fax " "
$answer1 = read-host "Please Make a Selection"
if ($answer1 -eq 1){
$location="Melbourne"
}
if ($answer1 -eq 2){
$location="Sydney"
}
if ($answer1 -eq 3){
$location="Adelaide"
}
if ($answer1 -eq 4){
$location="Brisbane"
}
if ($answer1 -eq 5){
$location="Perth"
}
$ExcelPath = 'E:\temp\FX MFD UserPIN.xlsx'
$Excel = New-Object -ComObject Excel.Application
$Excel.Visible = $true
$ExcelWorkBook = $Excel.Workbooks.Open($ExcelPath)
$ExcelWorkSheet = $Excel.WorkSheets.item("$location")
$Range = $ExcelWorkSheet.Range("A1").EntireColumn
$Search = $Range.find($user)
If($Search.value() -contains $user)
{
Write-Host "User FOUND, removing now"
$Search.value() = ""
}
else {
Write-Host "User NOT FOUND"
}
}
Error code is this:
You cannot call a method on a null-valued expression.
At E:\temp\testsest.ps1:35 char:12
+ If($Search.value() -contains $SearchString)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
How do I replace the $Search to get $user?
Range.Find() returns Nothing if no match is found.
Therefore, before you check if there is a match, you have to check if there's a null value in $Search.
if ($Search -ne $null) {
if ($Search.value -contains $user)
{
Write-Host "User FOUND, removing now"
$Search.value = ""
}
else {
Write-Host $Search.value," what did we find?!"
}
}
else {
Write-Host "User NOT FOUND"
}
Also, value is not a method, it's a property, so don't use round brackets.
Thanks Vesper. I've made a couple more changes and can confirm it works now.
if ($Search -ne $null) {
if ($Search.text -contains $user)
{
Write-Host "User FOUND, removing now"
$Range.replace($Search,"")
}
else {
Write-Host $Search.text," what did we find?!"
}
}
else {
Write-Host "User NOT FOUND"
}

Powershell NSlookup on DC's Forward and Reverse

$topDC1="10.254.90.17"
$topDC2="10.225.224.17"
$topDC3="10.110.33.32"
$topDC4="10.88.100.10"
$DomainName="office.adroot.company.net"
TRY{
$hostname = [System.Net.DNS]::GetHostByName($topDC1).HostName.toupper()
$ipaddress = [System.Net.Dns]::GetHostAddresses($DomainName) | select IPAddressToString -ExpandProperty IPAddressToString
# I want the below to loop foreach ip in the object, ns it against all 4 topDC's, then output each result :(
$NS1 = nslookup $ipaddress[0] $topDC1
Write-host $NS1
}
Catch{
write-host "error"
}
Here is my dirty code so far (just to keep it simple)
I am trying to automate this:
NSLOOKUP office.adroot.company.net
put the results into an object
for each ip in results, do an NSLOOKUP against our top level DC's.
find which DC's haven't been cleaned up after decommission (still in dns)
$DCList="10.254.90.17","10.225.224.17","10.110.33.32","10.88.100.10"
$DomainName="office.adroot.blorg.net","pcd.blorg.ca","blorg.ca","percom.adroot.blorg.net", "blorg.blorg.net","ibg.blorg.net","sacmcm.adroot.blorg.net","sysdev.adroot.blorg.net","adroot.blorg.net"
TRY{
foreach ($DomainNameItem in $DomainName){
Write-Host ""
Write-Host ""
Write-Host "Looking UP result"$DomainNameItem -foreground yellow
Write-Host ""
$hostname = [System.Net.DNS]::GetHostByName($DCListItem).HostName.toupper()
$ipaddress = [System.Net.Dns]::GetHostAddresses($DomainNameItem).IPAddressToString
foreach ($ip in $ipaddress){
Write-Host ""
Write-Host "Looking UP result"$ip -foreground green
foreach ($topdns in $DCList){
$RESULTS = nslookup $ip $topdns
Write-host $RESULTS
}
}
}
}
Catch{
write-host "error"
}
Write-Host ""
Write-Host ""
pause
Got it! This will save me tonnes of work determining if a DNS cleanup is necessary. Thanks guys, I'm learning just how great Powershell can be :)
Try this:
$topDomainControllers = #("10.254.90.17", "10.225.224.17", "10.110.33.32", "10.88.100.10")
$DomainName="office.adroot.company.net"
try {
$hostname = [System.Net.Dns]::GetHostByName($topDC1).HostName.ToUpper()
$ipAddresses = [System.Net.Dns]::GetHostAddresses($DomainName) |
select -ExpandProperty IPAddressToString
foreach ($ipAddress in $ipAddresses) {
$nslookupResult = nslookup $ipAddress
$foundIp = $nslookupResult[1] -match "^\D*(\d+\.\d+\.\d+\.\d+)$"
if ($foundIp -eq $false) {
continue
}
$domainController = $Matches[1]
if ($topDomainControllers.Contains($domainController)) {
Write-Output -Verbose "Found domain controller match for $domainController"
break
} else {
Write-Output -Verbose "No match found for domain controller $domainController"
}
}
} catch {
Write-Output "An error has occured: $_"
}

powershell Foreach-Object usage

I have script:
$servers = "server01", "s02", "s03"
foreach ($server in $servers) {
$server = (New-Object System.Net.NetworkInformation.Ping).send($servers)
if ($server.Status -eq "Success") {
Write-Host "$server is OK"
}
}
Error message:
An exception occured during a Ping request.
I need to ping each server in $servers array and display status. I think, that Foreach statement is not properly used, but I'm unable to find out where is the problem. Thank you for your advice
You should not be modifying the value of $server within the foreach loop. Declare a new variable (e.g. $result). Also, Ping.Send takes the individual server name, not an array of server names as an argument. The following code should work.
Finally, you will need to trap the PingException that will be thrown if the host is unreachable, or your script will print out a big red error along with the expected results.
$servers = "server1", "server2"
foreach ($server in $servers) {
& {
trap [System.Net.NetworkInformation.PingException] { continue; }
$result = (New-Object System.Net.NetworkInformation.Ping).send($server)
if ($result.Status -eq "Success") {
Write-Host "$server is OK"
}
else {
Write-Host "$server is NOT OK"
}
}
}

PowerShell BizTalk scripts WITHOUT using BizTalk provider for PowerShell

I have been using the excellent BizTalk Provider for PowerShell from Codeplex for a while now. However in my new company the build team are not comfortable using it so I need to rewrite all my handy configuration scripts to not use it.
I have re-done most of them but am having some problems finding examples of how to do the following two things:
Create host instances
Create send/receive adapter handers
Can anyone point me to examples of how to do these things WITHOUT the PowerShell provider for BizTalk please? I have done some looking and it seems like everyone uses this now.
Many thanks in advance.
OK here are my finished hacky powershell functions if anyone else needs them:
function write-WarnMessage([string]$message) {
Write-Host $(Get-Date) $message -ForegroundColor Yellow
}
function write-SucessMessage([string]$message) {
Write-Host $(Get-Date) $message -ForegroundColor Green
}
function write-InfoMessage([string]$message) {
Write-Host $(Get-Date) $message -ForegroundColor Blue -BackgroundColor White
}
function write-ErrorMessage ([string]$message) {
Write-Host $(Get-Date) $message -ForegroundColor Red
}
# Gets the execution directory
function Get-ScriptDirectory
{
$Invocation = (Get-Variable MyInvocation -Scope 1).Value
Split-Path $Invocation.MyCommand.Path
}
function Delete-Bts-Receive-Handler ( [string]$adapter, [string]$hostName )
{
try
{
[System.Management.ManagementObject]$objHandler = get-wmiobject 'MSBTS_ReceiveHandler' -namespace 'root\MicrosoftBizTalkServer' -filter "HostName='$hostName' AND AdapterName='$adapter'"
$objHandler.Delete()
write-SucessMessage "Deleted $adapter receive handler for $hostName"
}
catch [System.Management.Automation.RuntimeException]
{
if ($_.Exception.Message -eq "You cannot call a method on a null-valued expression.")
{
write-WarnMessage "$adapter receive handler for $hostName does not exist"
}
elseif ($_.Exception.Message.IndexOf("Cannot delete a receive handler that is used by") -ne -1)
{
write-WarnMessage "$adapter receive handler for $hostName is in use. Cannot delete."
}
else
{
write-Error "$adapter receive handler for $hostName could not be deleted: $_.Exception.ToString()"
}
}
}
function Delete-Bts-Send-Handler ( [string]$adapter, [string]$hostName )
{
try
{
[System.Management.ManagementObject]$objHandler = get-wmiobject 'MSBTS_SendHandler2' -namespace 'root\MicrosoftBizTalkServer' -filter "HostName='$hostName' AND AdapterName='$adapter'"
$objHandler.Delete()
write-SucessMessage "Deleted $adapter send handler for $hostName"
}
catch [System.Management.Automation.RuntimeException]
{
if ($_.Exception.Message -eq "You cannot call a method on a null-valued expression.")
{
write-WarnMessage "$adapter send handler for $hostName does not exist"
}
elseif ($_.Exception.Message.IndexOf("Cannot delete a send handler that is used by") -ne -1)
{
write-WarnMessage "$adapter send handler for $hostName is in use. Cannot delete."
}
else
{
write-Error "$adapter send handler for $hostName could not be deleted: $_.Exception.ToString()"
}
}
}
function Delete-Bts-Instance( [string]$hostName, [string]$Server )
{
try
{
# Unintall
[System.Management.ManagementObject]$objHostInstance = ([WmiClass]"root/MicrosoftBizTalkServer:MSBTS_HostInstance").CreateInstance()
$name = "Microsoft BizTalk Server " + $hostName + " " + $Server
$objHostInstance["Name"] = $name
$objHostInstance.Uninstall()
# Unmap
[System.Management.ManagementObject]$objServerHost = ([WmiClass]"root/MicrosoftBizTalkServer:MSBTS_ServerHost").CreateInstance()
$objServerHost["HostName"] = $hostName
$objServerHost["ServerName"] = $Server
$objServerHost.Unmap()
write-SucessMessage "Deleted host instance for $hostName on $Server"
}
catch [System.Management.Automation.RuntimeException]
{
write-Error "$hostName host instance on server $Server could not be deleted: $_.Exception.ToString()"
}
}
function Stop-Bts-HostInstance ( [string] $HostName, [string] $Server )
{
try
{
$filter = "HostName = '" + $HostName + "' and RunningServer = '" + $Server + "'"
$HostInstance = get-wmiobject "MSBTS_HostInstance" -namespace "root\MicrosoftBizTalkServer" -filter $filter
$HostInstanceState = $HostInstance.GetState().State
write-InfoMessage "Current state of $HostName instance on server $Server : $HostInstanceState (1=Stopped, 2=Start pending, 3=Stop pending, 4=Running, 8=Unknown)"
if ($HostInstanceState -eq 4)
{
$HostInstance.Stop()
$HostInstanceState = $HostInstance.GetState().State
write-SucessMessage "New state of $HostName instance on server $Server: $HostInstanceState (1=Stopped, 2=Start pending, 3=Stop pending, 4=Running, 8=Unknown)"
}
else
{
$HostInstanceState = $HostInstance.GetState().State
write-WarnMessage "Failed to stop host instance $HostName on server $Server because host instance state $HostInstanceState was not the expected value of 4 (running)"
}
}
catch [System.Management.Automation.RuntimeException]
{
write-Error "$hostName host instance could not be stopped on $Server : $_.Exception.ToString()"
}
}
function Delete-Bts-Host ( [string]$hostName )
{
# TODO: This only works intermittently
try
{
[System.Management.ManagementObject]$objHostSetting = get-wmiobject 'MSBTS_HostSetting' -namespace 'root\MicrosoftBizTalkServer' -filter "HostName='$hostName'"
$objHostSetting.Delete()
write-SucessMessage "Deleted host $hostName"
}
catch [System.Management.Automation.RuntimeException]
{
write-Error "$hostName host could not be deleted: $_.Exception.ToString()"
}
}
# function to create BizTalk host
function Create-Bts-Host(
[string]$hostName,
[int]$hostType,
[string]$ntGroupName,
[bool]$authTrusted,
[bool]$tracking,
[bool]$32BitOnly)
{
try
{
[System.Management.ManagementObject]$objHostSetting = ([WmiClass]"root/MicrosoftBizTalkServer:MSBTS_HostSetting").CreateInstance()
$objHostSetting["Name"] = $hostName
$objHostSetting["HostType"] = $hostType
$objHostSetting["NTGroupName"] = $NTGroupName
$objHostSetting["AuthTrusted"] = $authTrusted
$objHostSetting["IsHost32BitOnly"] = $32BitOnly
$objHostSetting["HostTracking"] = $tracking
$putOptions = new-Object System.Management.PutOptions
$putOptions.Type = [System.Management.PutType]::CreateOnly;
[Type[]] $targetTypes = New-Object System.Type[] 1
$targetTypes[0] = $putOptions.GetType()
$sysMgmtAssemblyName = "System.Management"
$sysMgmtAssembly = [System.Reflection.Assembly]::LoadWithPartialName($sysMgmtAssemblyName)
$objHostSettingType = $sysMgmtAssembly.GetType("System.Management.ManagementObject")
[Reflection.MethodInfo] $methodInfo = $objHostSettingType.GetMethod("Put", $targetTypes)
$methodInfo.Invoke($objHostSetting, $putOptions)
write-SucessMessage "Host $hostName created"
}
catch [System.Management.Automation.RuntimeException]
{
write-Error "$hostName host could not be created: $_.Exception.ToString()"
}
}
function Update-Bts-Host (
[string]$hostName,
[int]$hostType,
[string]$ntGroupName,
[bool]$authTrusted,
[bool]$tracking,
[bool]$32BitOnly)
{
try
{
[System.Management.ManagementObject]$objHostSetting = ([WmiClass]"root/MicrosoftBizTalkServer:MSBTS_HostSetting").CreateInstance()
$objHostSetting["Name"] = $hostName
$objHostSetting["HostType"] = $hostType
$objHostSetting["NTGroupName"] = $ntGroupName
$objHostSetting["AuthTrusted"] = $authTrusted
$objHostSetting["IsHost32BitOnly"] = $32BitOnly
$objHostSetting["HostTracking"] = $tracking
$putOptions = new-Object System.Management.PutOptions
$putOptions.Type = [System.Management.PutType]::UpdateOnly; # This tells WMI it's an update.
[Type[]] $targetTypes = New-Object System.Type[] 1
$targetTypes[0] = $putOptions.GetType()
$sysMgmtAssemblyName = "System.Management"
$sysMgmtAssembly = [System.Reflection.Assembly]::LoadWithPartialName($sysMgmtAssemblyName)
$objHostSettingType = $sysMgmtAssembly.GetType("System.Management.ManagementObject")
[Reflection.MethodInfo] $methodInfo = $objHostSettingType.GetMethod("Put", $targetTypes)
$methodInfo.Invoke($objHostSetting, $putOptions)
write-SucessMessage "Host updated"
}
catch [System.Management.Automation.RuntimeException]
{
write-Error "$hostName host could not be updated: $_.Exception.ToString()"
}
}
# function to create BizTalk send adapter handler
function Create-Bts-SendHandler([string]$adapter, [string]$hostName)
{
try
{
[System.Management.ManagementObject]$objSendHandler = ([WmiClass]"root/MicrosoftBizTalkServer:MSBTS_SendHandler2").CreateInstance()
$objSendHandler["AdapterName"] = $adapter
$objSendHandler["HostName"] = $hostName
$objSendHandler["IsDefault"] = $false
$putOptions = new-Object System.Management.PutOptions
$putOptions.Type = [System.Management.PutType]::CreateOnly;
[Type[]] $targetTypes = New-Object System.Type[] 1
$targetTypes[0] = $putOptions.GetType()
$sysMgmtAssemblyName = "System.Management"
$sysMgmtAssembly = [System.Reflection.Assembly]::LoadWithPartialName($sysMgmtAssemblyName)
$objSendHandlerType = $sysMgmtAssembly.GetType("System.Management.ManagementObject")
[Reflection.MethodInfo] $methodInfo = $objSendHandlerType.GetMethod("Put", $targetTypes)
$methodInfo.Invoke($objSendHandler, $putOptions)
write-SucessMessage "Send handler created for $adapter / $hostName"
}
catch [System.Management.Automation.RuntimeException]
{
write-Error "Send handler for $adapter / $hostName could not be created: $_.Exception.ToString()"
}
}
# function to create BizTalk receive adapter handler
function Create-Bts-ReceiveHandler([string]$adapter, [string]$hostName)
{
try
{
[System.Management.ManagementObject]$objReceiveHandler = ([WmiClass]"root/MicrosoftBizTalkServer:MSBTS_ReceiveHandler").CreateInstance()
$objReceiveHandler["AdapterName"] = $adapter
$objReceiveHandler["HostName"] = $hostName
$putOptions = new-Object System.Management.PutOptions
$putOptions.Type = [System.Management.PutType]::CreateOnly;
[Type[]] $targetTypes = New-Object System.Type[] 1
$targetTypes[0] = $putOptions.GetType()
$sysMgmtAssemblyName = "System.Management"
$sysMgmtAssembly = [System.Reflection.Assembly]::LoadWithPartialName($sysMgmtAssemblyName)
$objReceiveHandlerType = $sysMgmtAssembly.GetType("System.Management.ManagementObject")
[Reflection.MethodInfo] $methodInfo = $objReceiveHandlerType.GetMethod("Put", $targetTypes)
$methodInfo.Invoke($objReceiveHandler, $putOptions)
write-SucessMessage "Receive handler created for $adapter / $hostName"
}
catch [System.Management.Automation.RuntimeException]
{
write-Error "Receive handler for $adapter / $hostName could not be created: $_.Exception.ToString()"
}
}
# function to create BizTalk host instance
function Create-Bts-Instance([string]$hostName, [string]$login, [string]$password, [string]$Server)
{
try
{
[System.Management.ManagementObject]$objServerHost = ([WmiClass]"root/MicrosoftBizTalkServer:MSBTS_ServerHost").CreateInstance()
$objServerHost["HostName"] = $hostName
$objServerHost["ServerName"] = $Server
$objServerHost.Map()
[System.Management.ManagementObject]$objHostInstance = ([WmiClass]"root/MicrosoftBizTalkServer:MSBTS_HostInstance").CreateInstance()
$name = "Microsoft BizTalk Server " + $hostName + " " + $Server
$objHostInstance["Name"] = $name
$objHostInstance.Install($Login, $Password, $True)
write-SucessMessage "Created host instance for $hostName on $Server"
}
catch [System.Management.Automation.RuntimeException]
{
write-Error "$hostName host instance on server $Server could not be created: $_.Exception.ToString()"
}
}
function Start-Bts-HostInstance ( [string] $HostName, [string] $Server )
{
try
{
$filter = "HostName = '" + $HostName + "' and RunningServer = '" + $Server + "'"
$HostInstance = get-wmiobject "MSBTS_HostInstance" -namespace "root\MicrosoftBizTalkServer" -filter $filter
$HostInstanceState = $HostInstance.GetState().State
write-InfoMessage "Current state of $HostName instance on server $Server: $HostInstanceState (1=Stopped, 2=Start pending, 3=Stop pending, 4=Running, 8=Unknown)"
if ($HostInstanceState -eq 1)
{
$HostInstance.Start()
$HostInstanceState = $HostInstance.GetState().State
write-SucessMessage "New state of $HostName instance on server $Server: $HostInstanceState (1=Stopped, 2=Start pending, 3=Stop pending, 4=Running, 8=Unknown)"
}
else
{
$HostInstanceState = $HostInstance.GetState().State
write-WarnMessage "Failed to start host instance $HostName on server $Server because host instance state $HostInstanceState was not the expected value of 1 (stopped)"
}
}
catch [System.Management.Automation.RuntimeException]
{
write-Error "$hostName host instance could not be started on $Server : $_.Exception.ToString()"
}
}
function Install-BTSMsi ( [string]$bts_application, [string]$msi_package, [string]$install_env )
{
write-InfoMessage "Installing $msi_package in $bts_application for $install_env"
BTSTask ImportApp /ApplicationName:$bts_application /Package:$msi_package /Overwrite /Environment:$install_env
if ($LASTEXITCODE -ne 0) {
write-ErrorMessage "Failed to Import MSI $msi_package"
}
else
{
write-SucessMessage "Installed $bts_application for $install_env"
}
}
function Remove-BTSApplication ( [string]$appServer, [string]$appDatabase, [string]$appName )
{
write-InfoMessage "Uninstalling Application: $appName "
BTSTask RemoveApp /Server:"$appServer" /ApplicationName:"$appName" /Database:"$appDatabase" #| out-null
if ($LASTEXITCODE -ne 0) {
write-ErrorMessage "Failed to remove $appServer $appName"
}
else
{
write-SucessMessage "Removed $appName from $appServer"
}
}
# Accesses SSO and will require the build user account to belong to the SSO Admins group.
# Also requires Microsoft.BizTalk.ExplorerOM.dll to be loaded.
function StartStop-BTSApplication ( [string]$appServer, [string]$appName, [string]$appCommand )
{
if ( ($appName -eq '') -or ($appName -eq $null) )
{
throw 'you must supply the application name'
}
#write-InfoMessage " Finding Application: $appServer:$appName "
$exp = New-Object Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer
$exp.ConnectionString = Get-BTSConnectionString($appServer)
$app = $exp.Applications[$appName]
if($app -eq $null)
{
if ($appCommand -eq "stop" )
{
write-WarnMessage "WARNING failed to stop $appName"
}
else
{
write-WarnMessage "FAILED to start $appName"
}
}
else
{
switch -wildcard ( $app.Status.ToString() )
{
'Stopped'
{
if ($appCommand -eq "start" ) {
write-InfoMessage "Starting Application: $appName "
$null = $app.Start([Microsoft.BizTalk.ExplorerOM.ApplicationStartOption]::StartAll)
$null = $exp.SaveChanges()
write-SucessMessage " Started Application: $appName "
} else {
write-InfoMessage "Application Already Stopped: $appName "
}
}
'*Started'
{
# includes Started and PartiallyStarted
if ($appCommand -eq "stop" ) {
write-InfoMessage "Stopping Application: $appName "
$null = $app.Stop([Microsoft.BizTalk.ExplorerOM.ApplicationStopOption]::StopAll)
$null = $exp.SaveChanges()
write-SucessMessage " Stopped Application: $appName "
} else {
write-InfoMessage "Application Already Started : $appName "
}
}
'NotApplicable'
{
write-InfoMessage "Application doesn't require $appCommand"
}
default
{
$msg = "Unkown STATUS: " + $app.Status
write-ErrorMessage $msg
}
}
}
}
function Get-BTSConnectionString ( [string] $server )
{
$group = Get-WmiObject MSBTS_GroupSetting -n root\MicrosoftBizTalkServer -computername $server
$grpdb = $group.MgmtDBName
$grpsvr = $group.MgmtDBServerName
[System.String]::Concat("server=", $grpsvr, ";database=", $grpdb, ";Integrated Security=SSPI")
write-InfoMessage " Server: $grpsvr - Database $grpdb"
}
For 2) you should look into Microsoft.BizTalk.ExplorerOM
Using ReceiveHandler and SendHandler should give you what you need.
However there seems to be no way to control host instances, only hosts, using ExplorerOM.
Looks like you borrowed from Santhosh Benjamin's scripts to submit the PutOptions using reflection:
[Type[]] $targetTypes = New-Object System.Type[] 1
$targetTypes[0] = $putOptions.GetType()
$sysMgmtAssemblyName = “System.Management”
$sysMgmtAssembly = [System.Reflection.Assembly]::LoadWithPartialName($sysMgmtAssemblyName)
$objHostSettingType = $sysMgmtAssembly.GetType(“System.Management.ManagementObject”)
[Reflection.MethodInfo] $methodInfo = $objHostSettingType.GetMethod(“Put”,$targetTypes)
$methodInfo.Invoke($objHostSetting,$putOptions)
I tested this with several scripts I am currently working at, and found out (through sheer stubbernness) that you can simply use the Put method on the object, just as you were used to in C#:
$objHostSetting.Put($putOptions)
Cheers,
Charles.
Even if you can't use the Powershell library itself, nothing is stopping you from examining its source to see what it does to perform those functions, which is to interact with the Microsoft.BizTalk.ExplorerOM assembly.
There is also a very useful blog by Sandro Pereira with functions for handling hosts, host instances and adapter handlers
And also Tomas Restrepo set on GitHub
The one they didn't seem to cover was deleting a BizTalk host ...
function Remove-BizTalkHost(
[string] $hostName)
{
try
{
$strQuery = "MSBTS_HostSetting.Name='$hostName'";
$objPath = New-Object System.Management.ManagementPath
$objPath.Path = $strQuery
[System.Management.ManagementObject]$objHostSetting = ([WmiClass]"root/MicrosoftBizTalkServer:MSBTS_HostSetting").CreateInstance()
$objHostSetting.Path = $objPath
$objHostSetting.Delete()
Write-Host "Host $hostName was successfully deleted" -ForegroundColor DarkGreen
}
catch [System.Management.Automation.RuntimeException]
{
if ($_.Exception.Message.Contains("No instance was found with the specified key") -eq $true)
{
Write-Host "$hostName can't be deleted because already removed from the BizTalk group." -ForegroundColor DarkRed
}
else
{
Write-Error "$hostName host could not be deleted: $_.Exception.ToString()"
}
}
}