Powershell - Export csv for program name, version, installdate - powershell

im trying to run a command against a list of computers to find out information on the programs on the computers. then i would like to export that information on a Csv in the following format:
Computer name, McAfee Agent, version, Installdate
i wanted to get the list of these computers and the programs version numbers and installdate.
this command works, but not for exporting:
Get-WmiObject win32_product -ComputerName SYSTEMName01 | Where name -Match "McAfee Agent" | Select Name, Version, Installdate
I tried using the following code here, but this isn't working because it populates the information in Powershell then gives me a:
"RPC server is unavailable" red text.
and the Exported CSV document only gives me one populated row of the Name of the program and its version # and install date. but it doesn't populate the computer name it looked into and it doesn't list the other computers in the .txt document.
$computers = Get-content -Path "C:\nice\List-of-systems.txt"
Get-WmiObject win32_product -ComputerName $computers | Where name -Match "McAfee Agent" | Select Name, Version, Installdate |
Export-Csv -Path "C:\nice\computers-mcafee-status.csv"

If you're gonna go through the trouble of just querying single information, might as well query the system info a long with it.
<#
SYNTAX
Get-SystemInfo [[-ComputerName] <string[]>] [<CommonParameters>]
EXAMPLE
Get-SystemInfo -ComputerName SystemOne, SystemTwo
'SystemOne', 'SystemTwo' | Get-SystemInfo
Get-content -Path "C:\nice\List-of-systems.txt" | Get-SystemInfo
Get-content -Path "C:\nice\List-of-systems.txt" | Get-SystemInfo | Export-CSV C:\List-Of-Systems.csv -NoTypeInformation
#>
Function Get-SystemInfo{
[CmdletBinding()]
Param(
[Parameter(Mandatory=$False,
ValueFromPipeLine=$True,
ValueFromPipelineByPropertyName=$true,
HelpMessage='Enter Computer Name')]
[Alias('CN','Name')]
[String[]]$ComputerName = $env:COMPUTERNAME)
Process{
try{
#$ExportPath = "C:\nice\computers-mcafee-status.csv"
#if(-Not(Test-Path -Path '$ExportPath')){
#New-Item '$ExportPath' -ItemType File }
foreach($Computer in $ComputerName){
$CIMSession = New-CimSession -ComputerName $Computer -ErrorAction Stop
#$OS = Get-CimInstance -CimSession $CIMSession -Namespace Root/CIMv2 -ClassName WIN32_OperatingSystem -ErrorAction SilentlyContinue
$CS = Get-CimInstance -CimSession $CIMSession -Namespace Root/CIMv2 -ClassName WIN32_ComputerSystem -Property Model,Manufacturer,Username -ErrorAction SilentlyContinue
$BS = Get-CimInstance -CimSession $CIMSession -Namespace Root/CIMv2 -ClassName WIN32_BIOS -ErrorAction SilentlyContinue
$MAC = Get-CimInstance -CimSession $CIMSession -Namespace Root/CIMv2 -ClassName WIN32_NetworkAdapterConfiguration | Where-Object -Property Description -Like "*Ethernet*"
$MA = Get-CimInstance -CimSession $CIMSession -Namespace Root/CIMv2 -ClassName WIN32_Product | Where-Object Name -Match "McAfee Agent" -ErrorAction SilentlyContinue
[PSCustomobject] #{
"Computer Name" = $Computer
"Status" = "Online"
"Manufacturer" = if($CS.Manufacturer){$CS.Manufacturer}Else{"Unable to get Manufacturer"}
"Model" = if($CS.Model){$CS.Model}Else{"Unable to get Model"}
"User Logged in" = if($cs.UserName){$cs.UserName}Else{"No user logged in"}
"Serial Number" = if($BS.SerialNumber){$BS.SerialNumber}Else{"Unable to get Serial #"}
"MAC Address" = if($MAC.MACAddress){$MAC.MACAddress}Else{"Unable to get MAC Address"}
"McAfee InstallDate" = if($MA.InstallDate){$MA.InstallDate}Else{"Unable to get InstallDate"}
"McAfee Version" = if($Ma.Version){$MA.Version}Else{"Unable to get Version"}
} #| Export-Csv -Path '$ExportPath' -Append -NoTypeInformation
}
} Catch [Microsoft.Management.Infrastructure.CimException] {
[PSCustomobject] #{
"Computer Name" = $Computer
"Status" = "Offline"
"Manufacturer" = $null
"Model" = $null
"User Logged in" = $null
"Serial Number" = $null
"MAC Address" = $null
"McAfee InstallDate" = $null
"McAfee Version" = $null
} #| Export-Csv -Path '$ExportPath' -Append -NoTypeInformation
} Finally {
if($CIMSession){
Get-CimSession | Remove-CimSession
}
}
}
}
The issue with what you're trying to do is, you're not including the computername to be exported along with the other information. You also need to -Append to the file. The errors you receive mean that you just couldn't connect to the remote machine.

Related

How do i export this Script to csv

#I can't figure out where to place the Export-csv ...
It doesn't seem to work when I put it on the end with a pipe
foreach($ADMachineInOU in $(Get-ADComputer -Filter * -SearchBase "OU=Win10Modern,OU=LN,OU=Workstations,DC=cooley,DC=com" | Select -ExpandProperty Name))
{
# Test if machine is online
if(Test-Connection -ComputerName $ADMachineInOU -Count 1 -ErrorAction SilentlyContinue)
{
Write-Host $ADMachineInOU -ForegroundColor Green
$CimSession = New-CimSession -ComputerName $ADMachineInOU
Get-NetAdapter -CimSession $CimSession -Name "Wi-Fi" | select PSComputerName,DriverVersion
Remove-CimSession -CimSession $CimSession
}
else
{
Write-Host $ADMachineInOU -ForegroundColor Gray
}
Remove-Variable CimSession,ADMachineInOU -ErrorAction SilentlyContinue
}
I would suggest something like this:
$ADComputers = Get-ADComputer -Filter * -SearchBase "OU=Win10Modern,OU=LN,OU=Workstations,DC=cooley,DC=com"
$Report = #()
foreach ($ADComputer in $ADComputers)
{
$HostName = $ADComputer.name
# Test if machine is online
$Ping = Test-Connection $HostName -Count -Quiet -ErrorAction SilentlyContinue
If ($Ping)
{
Write-Host $HostName -ForegroundColor Green
$CimSession = New-CimSession -ComputerName $HostName
$Adapter = Get-NetAdapter -CimSession $CimSession -Name "Wi-Fi"
$Hash = #{
Hostname = $HostName
Hardware = "Wi-Fi"
PSComputerName = $Adapter.PSComputerName
DriverVersion = $Adapter.DriverVersion
}
Remove-CimSession -CimSession $CimSession
$Report += New-Object psobject -Property $hash
}
else
{
Write-Host $ADMachineInOU -ForegroundColor Gray
}
}
$Report | export-csv "c:\Temp\Report.csv" -NoTypeInformation
Simply capture the results from Get-NetAdapter in a variable. Make sure only wanted objects are output in the foreach loop:
$searchBase = "OU=Win10Modern,OU=LN,OU=Workstations,DC=cooley,DC=com"
$result = foreach($ADMachineInOU in (Get-ADComputer -Filter * -SearchBase $searchBase).Name) {
# Test if machine is online
if (Test-Connection -ComputerName $ADMachineInOU -Count 1 -Quiet -ErrorAction SilentlyContinue) {
Write-Host $ADMachineInOU -ForegroundColor Green
$CimSession = New-CimSession -ComputerName $ADMachineInOU
Get-NetAdapter -CimSession $CimSession -Name "Wi-Fi" | select PSComputerName,DriverVersion
# ignore the output from Remove-CimSession to not pollute the captured results
$null = Remove-CimSession -CimSession $CimSession
}
else {
Write-Host "Computer $ADMachineInOU did not respond.." -ForegroundColor Gray
}
}
# now export to Csv file
$result | Export-Csv -Path 'X:\Path\to\Output.Csv' -NoTypeInformation
P.S. I think you want to use -Name '*Wi-Fi*' for Get-NetAdapter..

Powershell script in columns instead of rows

I was trying to write a script which would use a text file with hostnames and needs to generate a file with the extra data. I can only manage to get it in rows instead of columns:
Model:
Bios Version:
TPM OEM Ver:
User logged In:
I would also like to get the emailaddress from the logged on user. I was thinking to use get-aduser. Could I add another foreach after the current code, using the column with the usernames? How would I do this?
All help is greatly appreciated!
My code is:
$output = foreach ($hostname in Get-Content C:\temp\hostnames.txt)
{
$computerinfo = get-ciminstance -computername $hostname Win32_ComputerSystem
$computerBIOS = get-ciminstance -computername $hostname Win32_BIOS
$tpm = Get-ciminstance -class Win32_Tpm -namespace root\CIMV2\Security\MicrosoftTpm -ComputerName $hostname
"Hostname: " + $computerinfo.name
"Model: " + $computerinfo.Model
"Bios Version: " + $computerBIOS.smbiosbiosversion
"TPM OEM Ver: " + $tpm.ManufacturerVersion
"User logged In: " + $computerinfo.UserName
}
$output | out-file 'C:\Temp\hostnames3.txt' -append
You should use the CSV file format instead of plain text for structured data. That makes it easier to use them for further steps if needed.
$output =
foreach ($hostname in Get-Content C:\temp\hostnames.txt) {
$computerinfo = Get-CimInstance -ComputerName $hostname -ClassName Win32_ComputerSystem
$computerBIOS = Get-CimInstance -ComputerName $hostname -ClassName Win32_BIOS
$tpm = Get-CimInstance -Namespace root\CIMV2\Security\MicrosoftTpm -ComputerName $hostname -ClassName Win32_Tpm
[PSCustomObject]#{
Hostname = $computerinfo.name
Model = $computerinfo.Model
Bios_Version = $computerBIOS.smbiosbiosversion
TPM_OEM_Ver = $tpm.ManufacturerVersion
User_logged_In = $computerinfo.UserName
}
}
$output |
Export-Csv -Path 'C:\Temp\hostnames3.csv' -NoTypeInformation
In my experience the UserName property of the CIM-Class Win32_ComputerSystem is unreliable to determine the logged on user. I usually use good old quser.exe like this:
$UserQuery = ( C:\Windows\System32\quser.exe /server:$hostname 2> null)
if ($UserQuery) {
$UserQuery[1].Trim() -match "^(\S+)\s+.*((\d{2}\.){2}\d{4}\s+\d{2}:\d{2})" | Out-Null
$LoggedOnUser = $Matches[1]
$LogonTime = Get-Date -Date $Matches[2]
}
Then you can use $LoggedOnUser and $LogonTime to include it in your output object if you like.
Of course you can include a additional AD query for more information about the logged on user.

How to show remote computers mapped drive path?

I got this to work locally however on a remote system it doesn't show the path but only the drive letter. My goal is to get it to show the drive path of the remote host.
Also sometimes it doesn't show all the drive that are mapped to the remote computer and I don't know why.
I have tried changing Win32_LogicalDisk to MappedLogicalDisk but it just results to no information.
$DISK = Get-WmiObject -computer $compname Win32_LogicalDisk
foreach ($device in $DISK){
Write-Host "Drive: " $device.name
Write-Host "Path: " $device.ProviderName
""
}
Pause
CheckHost
Try one of these examples:
This one...
$ComputerName = "ServerName"
gwmi win32_mappedlogicaldisk -ComputerName $ComputerName |
select SystemName, Name, ProviderName, SessionID |
foreach {
$disk = $_
$user = gwmi Win32_LoggedOnUser -ComputerName $ComputerName |
where { ($_.Dependent.split("=")[-1] -replace '"') -eq $disk.SessionID} |
foreach {$_.Antecedent.split("=")[-1] -replace '"'}
$disk | select Name, ProviderName, #{n = "MappedTo"; e = {$user} }
}
Or this one
function Get-MappedDrives($ComputerName)
{
$output = #()
if(Test-Connection -ComputerName $ComputerName -Count 1 -Quiet)
{
$Hive = [long]$HIVE_HKU = 2147483651
$sessions = Get-WmiObject -ComputerName $ComputerName -Class win32_process |
?{$_.name -eq "explorer.exe"}
if($sessions)
{
foreach($explorer in $sessions)
{
$sid = ($explorer.GetOwnerSid()).sid
$owner = $explorer.GetOwner()
$RegProv = get-WmiObject -List -Namespace "root\default" -ComputerName $ComputerName |
Where-Object {$_.Name -eq "StdRegProv"}
$DriveList = $RegProv.EnumKey($Hive, "$($sid)\Network")
if($DriveList.sNames.count -gt 0)
{
foreach($drive in $DriveList.sNames)
{
$output += "$($drive)`t$(($RegProv.GetStringValue($Hive, "$($sid)\Network\$($drive)",
"RemotePath")).sValue)`t$($owner.Domain)`t$($owner.user)`t$($ComputerName)"
}
}
else{write-debug "No mapped drives on $($ComputerName)"}
}
}
else{write-debug "explorer.exe not running on $($ComputerName)"}
}
else{write-debug "Can't connect to $($ComputerName)"}
return $output
}
<#
#Enable if you want to see the write-debug messages
$DebugPreference = "Continue"
$list = "Server01", "Server02"
$report = $(foreach($ComputerName in $list){Get-MappedDrives $ComputerName}) |
ConvertFrom-Csv -Delimiter `t -Header Drive, Path, Domain, User, Computer
#>

PowerShell Set-ADComputer description based on the input

I have a code which runs trough Active Directory computers objects to collect information. Part of that information is then updated on Active directory description field.
My problem is that when I get the Exception.Message the AD object of a computer is still updated with the last found computer information.
I would like to find out how can I:
Update AD description when there is Exception.Message
Update Ad description with populated system info
Attached is the script I'm using but can't figure out where to put the output for the two Set-ADComputer statements
# Getting computers from Active Directory
$Computers = Get-ADComputer -Filter {Enabled -eq $true} | select -expand name
Foreach($computer in $computers)
# Checking if the computer is Online
{
if(!(Test-Connection -ComputerName $computer -BufferSize 16 -Count 1 -ea 0 -quiet))
{write-host "Cannot reach $Computer is offline" -ForegroundColor red}
else {
$Output = #()
Try{
$xx = Get-WmiObject win32_computersystem -ComputerName $Computer -ErrorAction Stop
$in = Get-WmiObject Win32_OperatingSystem -ComputerName $Computer -ErrorAction Stop
$mc = Get-WmiObject -class Win32_NetworkAdapterConfiguration -Filter "IPEnabled='True'" -ComputerName $Computer -ErrorAction Stop
$sr = Get-WmiObject win32_bios -ComputerName $Computer -ErrorAction Stop
$Xr = Get-WmiObject –class Win32_processor -ComputerName $Computer -ErrorAction Stop
$ld = Get-ADComputer $Computer -properties Name,Lastlogondate,ipv4Address,enabled,description,DistinguishedName -ErrorAction Stop
$r = "{0} GB" -f ((Get-WmiObject Win32_PhysicalMemory -ComputerName $Computer -ErrorAction Stop | Measure-Object Capacity -Sum).Sum / 1GB)
$x = Get-WmiObject win32_computersystem -ComputerName $Computer -ErrorAction Stop | select #{Name = "Type";Expression = {if (($_.pcsystemtype -eq '2') )
{'Laptop'} Else {'Desktop Or Other'}}},Manufacturer,#{Name = "Model";Expression = {if (($_.model -eq "$null") ) {'Virtual'} Else {$_.model}}},username
$t= New-Object PSObject -Property #{
SerialNumber = $sr.serialnumber -replace "-.*"
Computername = $ld.name
IPaddress = $ld.ipv4Address
MACaddress = $mc.MACAddress
Enabled = $ld.Enabled
Description = $ld.description
OU = $ld.DistinguishedName.split(',')[1].split('=')[1]
DC = $xx.domain
Type = $x.type
Manufacturer = $x.Manufacturer
Model = $x.Model
RAM = $R
ProcessorName = ($xr.name | Out-String).Trim()
NumberOfCores = ($xr.NumberOfCores | Out-String).Trim()
NumberOfLogicalProcessors = ($xr.NumberOfLogicalProcessors | Out-String).Trim()
Addresswidth = ($xr.Addresswidth | Out-String).Trim()
Operatingsystem = $in.caption
InstallDate = ([WMI] '').ConvertToDateTime($in.installDate)
LastLogonDate = $ld.lastlogondate
LoggedinUser = $x.username
}
$Output += $t
}
Catch [Exception]
{
$ErrorMessage = $_.Exception.Message
Add-Content -value "$Computer, $ErrorMessage, skipping to next" $txt
Set-ADComputer $Computer -Description $ErrorMessage
}
}
# Output file location to be chnaged as needed
$file="C:\scripts\reports\AD-Inentory_$((Get-Date).ToString('MM-dd-yyyy')).csv"
$txt="c:\scripts\reports\AD-Inentory-error_$((Get-Date).ToString('MM-dd-yyyy')).txt"
$desc="$($mc.MACAddress) ( $($sr.serialnumber -replace "-.*") ) $($x.Model) | $((Get-Date).ToString('MM-dd-yyyy'))"
# Properties to be included in the output file
$Output | select Computername,Enabled,Description,IPaddress,MACaddress,OU,DC,Type,SerialNumber,Manufacturer,Model,RAM,ProcessorName,NumberOfCores,NumberOfLogicalProcessors,Addresswidth,Operatingsystem,InstallDate,LoggedinUser,LastLogonDate | export-csv -Append $file -NoTypeInformation
Set-ADComputer $Computer -Description $desc -verbose
}
It looks like the reason why it had the problem behaviour is it was catching the error, and setting the description as you wanted with the error.
However it would then continue on to evaluate the code outside of the catch and the else block, since it failed on the current computer the variables used to build the description variable still contained data from the previous computer that was successful and then update the failed computer again.
You could fix this by using the continue statement at the bottom of the catch block to skip the rest of the code for that iteration and move to the next item in the loop.
That solution would look like this:
Catch [Exception]
{
$ErrorMessage = $_.Exception.Message
Add-Content -value "$Computer, $ErrorMessage, skipping to next" $txt
Set-ADComputer $Computer -Description $ErrorMessage
## add continue statement here
continue
}
continue statement documentation here and examples here.
The other option is you restructure your code to make sure this cannot happen, like below.
I think this will fix your issue and do what you are trying to achieve. I put comments in the code around the changes I made (denoted by the ##) feel free to ask questions.
I would recommend you use more descriptive variable names.
## No Need to define these in the foreach loop
# Output file location to be chnaged as needed
$file = "C:\scripts\reports\AD-Inentory_$((Get-Date).ToString('MM-dd-yyyy')).csv"
$txt = "c:\scripts\reports\AD-Inentory-error_$((Get-Date).ToString('MM-dd-yyyy')).txt"
# Getting computers from Active Directory
## Update to use pipeline
Get-ADComputer -Filter {Enabled -eq $true} | Foreach-Object {
$computer = $_.Name
if(!(Test-Connection -ComputerName $computer -BufferSize 16 -Count 1 -ea 0 -quiet))
{
write-host "Cannot reach $Computer is offline" -ForegroundColor red
}
else
{
Try
{
## No Longer Need this because we are uisng the pipe line
#$Output = #()
$xx = Get-WmiObject win32_computersystem -ComputerName $Computer -ErrorAction Stop
$in = Get-WmiObject Win32_OperatingSystem -ComputerName $Computer -ErrorAction Stop
$mc = Get-WmiObject -class Win32_NetworkAdapterConfiguration -Filter "IPEnabled='True'" -ComputerName $Computer -ErrorAction Stop
$sr = Get-WmiObject win32_bios -ComputerName $Computer -ErrorAction Stop
$Xr = Get-WmiObject –class Win32_processor -ComputerName $Computer -ErrorAction Stop
$ld = Get-ADComputer $Computer -properties Name, Lastlogondate, ipv4Address, enabled, description, DistinguishedName -ErrorAction Stop
$r = "{0} GB" -f ((Get-WmiObject Win32_PhysicalMemory -ComputerName $Computer -ErrorAction Stop | Measure-Object Capacity -Sum).Sum / 1GB)
$x = Get-WmiObject win32_computersystem -ComputerName $Computer -ErrorAction Stop | select #{Name = "Type"; Expression = {if (($_.pcsystemtype -eq '2') )
{'Laptop'} Else {'Desktop Or Other'}}
}, Manufacturer, #{Name = "Model"; Expression = {if (($_.model -eq "$null") ) {'Virtual'} Else {$_.model}}}, username
## Output on creation
New-Object PSObject -Property #{
SerialNumber = $sr.serialnumber -replace "-.*"
Computername = $ld.name
IPaddress = $ld.ipv4Address
MACaddress = $mc.MACAddress
Enabled = $ld.Enabled
Description = $ld.description
OU = $ld.DistinguishedName.split(',')[1].split('=')[1]
DC = $xx.domain
Type = $x.type
Manufacturer = $x.Manufacturer
Model = $x.Model
RAM = $R
ProcessorName = ($xr.name | Out-String).Trim()
NumberOfCores = ($xr.NumberOfCores | Out-String).Trim()
NumberOfLogicalProcessors = ($xr.NumberOfLogicalProcessors | Out-String).Trim()
Addresswidth = ($xr.Addresswidth | Out-String).Trim()
Operatingsystem = $in.caption
InstallDate = ([WMI] '').ConvertToDateTime($in.installDate)
LastLogonDate = $ld.lastlogondate
LoggedinUser = $x.username
}
## Only do this kind of update if it hasnt failed yet
$desc = "$($mc.MACAddress) ( $($sr.serialnumber -replace "-.*") ) $($x.Model) | $((Get-Date).ToString('MM-dd-yyyy'))"
# Properties to be included in the output file
Set-ADComputer $Computer -Description $desc -verbose
## No longer need this
# $t
}
Catch [Exception]
{
$ErrorMessage = $_.Exception.Message
Add-Content -value "$Computer, $ErrorMessage, skipping to next" $txt
Set-ADComputer $Computer -Description $ErrorMessage
continue
}
}
} | select Computername, Enabled, Description, IPaddress, MACaddress, OU, DC, Type, SerialNumber, Manufacturer, Model, RAM, ProcessorName, NumberOfCores, NumberOfLogicalProcessors, Addresswidth, Operatingsystem, InstallDate, LoggedinUser, LastLogonDate | export-csv -Append $file -NoTypeInformation
After looking at the suggestion to include continue statement I was able to achieve the solution to my problem with the following final script:
# Output file location to be changed as needed
$file="C:\scripts\reports\AD-Inentory_$((Get-Date).ToString('MM-dd-yyyy')).csv"
$txt="c:\scripts\reports\AD-Inentory-error_$((Get-Date).ToString('MM-dd-yyyy')).txt"
# Getting computers from Active Directory
$Computers = Get-ADComputer -Filter {Enabled -eq $true} | select -expand name
Foreach($computer in $computers){
if(!(Test-Connection -ComputerName $computer -BufferSize 16 -Count 1 -ea 0 -quiet))
{
write-host "Cannot reach $Computer is offline" -ForegroundColor red
}
else
{
$Output = #()
Try
{
$xx = Get-WmiObject win32_computersystem -ComputerName $Computer -ErrorAction Stop
$in = Get-WmiObject Win32_OperatingSystem -ComputerName $Computer -ErrorAction Stop
$mc = Get-WmiObject -class Win32_NetworkAdapterConfiguration -Filter "IPEnabled='True'" -ComputerName $Computer -ErrorAction Stop
$sr = Get-WmiObject win32_bios -ComputerName $Computer -ErrorAction Stop
$Xr = Get-WmiObject –class Win32_processor -ComputerName $Computer -ErrorAction Stop
$ld = Get-ADComputer $Computer -properties Name,Lastlogondate,ipv4Address,enabled,description,DistinguishedName -ErrorAction Stop
$r = "{0} GB" -f ((Get-WmiObject Win32_PhysicalMemory -ComputerName $Computer -ErrorAction Stop | Measure-Object Capacity -Sum).Sum / 1GB)
$x = Get-WmiObject win32_computersystem -ComputerName $Computer -ErrorAction Stop | select #{Name = "Type";Expression = {if (($_.pcsystemtype -eq '2') )
{'Laptop'} Else {'Desktop Or Other'}}
},Manufacturer,#{Name = "Model";Expression = {if (($_.model -eq "$null") ) {'Virtual'} Else {$_.model}}},username
## Output on creation
$t= New-Object PSObject -Property #{
SerialNumber = $sr.serialnumber -replace "-.*"
Computername = $ld.name
IPaddress = $ld.ipv4Address
MACaddress = $mc.MACAddress
Enabled = $ld.Enabled
Description = $ld.description
OU = $ld.DistinguishedName.split(',')[1].split('=')[1]
DC = $xx.domain
Type = $x.type
Manufacturer = $x.Manufacturer
Model = $x.Model
RAM = $R
ProcessorName = ($xr.name | Out-String).Trim()
NumberOfCores = ($xr.NumberOfCores | Out-String).Trim()
NumberOfLogicalProcessors = ($xr.NumberOfLogicalProcessors | Out-String).Trim()
Addresswidth = ($xr.Addresswidth | Out-String).Trim()
Operatingsystem = $in.caption
InstallDate = ([WMI] '').ConvertToDateTime($in.installDate)
LastLogonDate = $ld.lastlogondate
LoggedinUser = $x.username
}
# Only do this kind of update if it hasn't failed yet
$Output += $t
$desc="$($mc.MACAddress) ( $($sr.serialnumber -replace "-.*") ) $($x.Model) | $((Get-Date).ToString('MM-dd-yyyy'))"
Set-ADComputer $Computer -Description $desc -verbose
$Output | select Computername,Enabled,Description,IPaddress,MACaddress,OU,DC,Type,SerialNumber,Manufacturer,Model,RAM,ProcessorName,NumberOfCores,NumberOfLogicalProcessors,Addresswidth,Operatingsystem,InstallDate,LoggedinUser,LastLogonDate | export-csv -Append $file -NoTypeInformation
}
Catch [Exception]
{
# Only do this kind of update if it has failed
$ErrorMessage = $_.Exception.Message
Add-Content -value "$Computer, $ErrorMessage, skipping to next" $txt
Set-ADComputer $Computer -Description $ErrorMessage
continue
}
}
}

Find running service instances for BizTalk Application for different state

I have the below PowerShell script to find out all different BizTalk states :
Instances Ready to Run
Active Instances
Dehydrated Instances
Instances in Breakpoint
Suspended Orchestrations
Suspended Messages
Routing Failures
Isolated Adapter Failures
PowerShell Script
# SQL Settings
$BTSSQLInstance = get-wmiobject MSBTS_GroupSetting -namespace root\MicrosoftBizTalkServer | select-object -expand MgmtDbServerName
$BizTalkManagementDb = get-wmiobject MSBTS_GroupSetting -namespace root\MicrosoftBizTalkServer | select-object -expand MgmtDbName
# Connect the BizTalk Management database
[void] [System.reflection.Assembly]::LoadWithPartialName("Microsoft.BizTalk.ExplorerOM")
$BTSCatalog = New-Object Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer
$BTSCatalog.ConnectionString = "SERVER=$BTSSQLInstance;DATABASE=$BizTalkManagementDb;Integrated Security=SSPI"
# Get BizTalk Service Instance Information
[ARRAY]$readyToRun = get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter '(ServiceStatus = 1)' -ErrorAction SilentlyContinue
[ARRAY]$active = get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter '(ServiceStatus = 2) and not(ServiceClass = 16)' -ErrorAction SilentlyContinue
[ARRAY]$dehydrated = get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter '(ServiceStatus = 8)' -ErrorAction SilentlyContinue
[ARRAY]$breakpoint = get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter '(ServiceStatus = 64)' -ErrorAction SilentlyContinue
[ARRAY]$suspendedOrchs = get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter '(ServiceClass = 1) and (ServiceStatus = 4 or ServiceStatus = 32)' -ErrorAction SilentlyContinue
[ARRAY]$suspendedMessages = get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter '(ServiceClass = 4) and (ServiceStatus = 4 or ServiceStatus = 32)' -ErrorAction SilentlyContinue
[ARRAY]$suspendedRouting = get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter '(ServiceClass = 64)' -ErrorAction SilentlyContinue
[ARRAY]$suspendedIsolated = get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter '(ServiceClass = 32) and (ServiceStatus = 4 or ServiceStatus = 32)' -ErrorAction SilentlyContinue
# Display BizTalk Service Instance Information
Write-Host "`nService Instance Information" -fore DarkGray
Write-Host "Instances Ready to Run:" $readyToRun.Count
Write-Host "Active Instances:" $active.Count
Write-Host "Dehydrated Instances:" $dehydrated.Count
Write-Host "Instances in Breakpoint:" $breakpoint.Count
Write-Host "Suspended Orchestrations:" $suspendedOrchs.count
Write-Host "Suspended Messages:" $suspendedMessages.count
Write-Host "Routing Failures:" $suspendedRouting.count
Write-Host "Isolated Adapter Failures:" $suspendedIsolated.count
Is there any WMI object to concatenate related activities running instances for BizTalk Application?
Like Application name = Microsoft.Practices.ESB and how many active running instances there are? If it's more that 20 send me email notification.
Please advise me how we can achieve that functionally using powershell also I have seen MSBTS_ServiceInstance wmiobject not providing BizTalk Application property.
Reference -- BizTalk Server Health Check PowerShell Script
I think this is what you need Get Biztalk serviceInstance details with Powershell
The trick is filter by Assembly Name with wildcards as:
Get-WmiObject -Class "MSBTS_ServiceInstance" -Namespace 'root\MicrosoftBizTalkServer' | Where-Object { $_.ServiceClass -eq "1" -and ($_.ServiceStatus -eq "4" -or $_.ServiceStatus -eq "32") -and $_.AssemblyName -like "*BizTalkMassCopy*" } | measure
This script will give you results for All your application Active,ReadytoRun and Dehydrated service Instances status:
# SQL Settings
$BTSSQLInstance = get-wmiobject MSBTS_GroupSetting -namespace root\MicrosoftBizTalkServer | select-object -expand MgmtDbServerName
$BizTalkManagementDb = get-wmiobject MSBTS_GroupSetting -namespace root\MicrosoftBizTalkServer | select-object -expand MgmtDbName
# Connect the BizTalk Management database
[void] [System.reflection.Assembly]::LoadWithPartialName("Microsoft.BizTalk.ExplorerOM")
$BTSCatalog = New-Object Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer
$BTSCatalog.ConnectionString = "SERVER=$BTSSQLInstance;DATABASE=$BizTalkManagementDb;Integrated Security=SSPI"
# Get BizTalk Application Information
$applications = $BTSCatalog.Applications
# Display BizTalk Application Information
Write-Host "`nBizTalk Applications ("$applications.Count")" -fore DarkGray
Foreach ($application in $applications) {
if ($application.Status -eq "Started") {
[ARRAY]$readyToRun = get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter '(ServiceStatus = 1)' -ErrorAction SilentlyContinue | Where-Object { $_.AssemblyName -like $application.Name }
[ARRAY]$active = get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter '(ServiceStatus = 2) and not(ServiceClass = 16)' -ErrorAction SilentlyContinue | Where-Object { $_.AssemblyName -like $application.Name }
[ARRAY]$dehydrated = get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter '(ServiceStatus = 8)' -ErrorAction SilentlyContinue | Where-Object { $_.AssemblyName -like $application.Name }
Write-Host "`nService Instance Information for" $application.Name -fore DarkGray
Write-Host "Instances Ready to Run:" $readyToRun.Count
Write-Host "Active Instances:" $active.Count
Write-Host "Dehydrated Instances:" $dehydrated.Count
}
}