PowerShell

Active Directory

Date and Time

Exchange

Event logs

Files and Folders

Misc

Ping

Ports

Process

Registry

SCOM

Active Directory

Computers

Get basic computer info by name

Get-ADComputer -Filter 'Name -eq "COMPUTER_NAME"'

Get-ADComputer -Filter 'dnshostname -eq "COMPUTER_NAME"'

Search different domain name (use DNS name):

Get-ADComputer -Filter {Name -eq "COMPUTER_NAME"} -Server "DOMAIN_NAME"

This will get all server OS including domain controllers.

Get-ADComputer -Filter 'operatingsystem -like "*server*"' -Properties name, DNSHostName, operatingsystem, enabled, lastLogonTimestamp | sort name | select -Property NAME, DNSHOSTNAME, OPERATINGSYSTEM, ENABLED, @{n = "LASTLOGON"; e = { [datetime]::fromfiletime($_."lastLogonTimestamp")}} | Export-Csv C:\temp\Server_OS.csv -NoTypeInformation

Get server OS and write to csv

As above just some different properties.

Get-ADComputer -Filter 'operatingsystem -like "*server*"' -Properties name, DNSHostName, operatingsystem, CanonicalName, enabled, LastLogonDate, whenChanged, whenCreated | sort name | select -Property NAME, DNSHOSTNAME, OPERATINGSYSTEM, CANONICALNAME, ENABLED, LASTLOGONDATE, WHENCHANGED, WHENCREATED | Export-Csv C:\temp\Server_OS.csv -NoTypeInformation

Query multiple computer accounts in AD

$erroractionpreference=continue
$a=gc C:\temp\file.txt
foreach ($i in $a) {
try {
$x=Get-ADComputer -Identity $i -Properties name, operatingsystem | select -Property name, operatingsystem
$os=$x.operatingsystem
"$i^$os"
}
catch {
"$i^NOT FOUND"
}}

Get server OS, enabled, logged in last 7 days

4/5/2023. Still being tested.

$Last7Days=(Get-Date).AddDays(-7)
$Filter='enabled -eq "true" -and operatingsystem -like "*server*" -and lastLogonTimestamp -gt $Last7Days'
(get-adcomputer -Filter $Filter -Properties name, DNSHostName, operatingsystem, enabled, lastLogonTimestamp, LastLogon | sort name | select -Property name, DNSHostName, operatingsystem, enabled, @{n="lastLogonTimestamp";e={[datetime]::fromfiletime($_."lastLogonTimestamp")}}, @{n="LastLogon";e={[datetime]::fromfiletime($_."LastLogon")}}).count

Get domain controllers from current domain and write to csv

Get-ADDomainController -filter * | sort name | select name, hostname, domain, enabled, OperatingSystem | Export-Csv DC_OS.csv

Groups

Get group members

Get-ADGroupMember -Identity GROUP_NAME | sort name | ft name

Get recursive group membership

This will get members of all sub-groups as well.

Get-ADGroupMember -Identity GROUP_NAME -Recursive | sort name | ft name

Get user's group membership (show full DN)

Get-ADUser -Identity USER_NAME -Properties memberof | Select-Object -ExpandProperty memberof

Get user's group membership (show group name only)

Get-ADUser -Identity USER_NAME  -Properties memberof | Select-Object -ExpandProperty memberof | Get-ADGroup -Properties name | Select-Object name

Search for a group

Get-ADGroup -Filter {name -like "*GROUP_NAME *"} | sort name | select name

Get members of a group

Get-ADGroupMember -Identity "GROUP_NAME " -Recursive | sort name | select name

Users

Get basic user info

Get-ADUser -Identity USER_NAME -Properties *

Get password expiry for user

Get-ADUser -Filter 'SamAccountName -like "*USER_NAME*"' -Server DC_OR_DOMAIN_FQDN -Properties DisplayName, SamAccountName, UserPrincipalName, Enabled, LastLogonDate, LockedOut, AccountExpirationDate, PasswordExpired, msDS-UserPasswordExpiryTimeComputed, PasswordLastSet | ft @{Name = "Display Name"; Expression = {$_.DisplayName}}, @{Name = "Username"; Expression = {$_.SamAccountName}}, @{Name = "UserPrincipalName"; Expression = {$_.UserPrincipalName}}, @{Name = "Enabled"; Expression = {$_.Enabled}}, @{Name = "LastLogon"; Expression = {$_.LastLogonDate}}, @{Name = "Locked"; Expression = {$_.LockedOut}}, @{Name = "Account Expires"; Expression = {$_.AccountExpirationDate}}, @{Name = "Password Expired"; Expression = {$_.PasswordExpired}}, @{Name = "Password Expiry"; Expression = {[datetime]::fromfiletime($_."msDS-UserPasswordExpiryTimeComputed")}}, @{Name = "Password Last Set"; Expression = {$_.PasswordLastSet}}

Get password expiry for single user with command prompt

Not PowerShell but including here anyway.

net user USER_NAME /domain | findstr /i "expires"

Search for a user

Get-ADUser -Filter {name -like "*USER_NAME*"} | sort name | select name

Get email addresses of users from file

This assumes the files contains users listed as firstname lastname which is the Name property of the account. It also looks for user acounts starting with u.

$a=gc C:\temp\file.txt
foreach ($i in $a) {
Get-ADUser -Filter 'Name -eq $i '-Properties EmailAddress | where {$_.SamAccountName -like "u*"} | select EmailAddress
}

Date and Time

Conversion examples

Convert UTC to local time

This should work for most dates/times returned in UTC. It first needs to convert to local time, then it formats it to local date.

Note: The property in red might be different depending on the data returned.

$TimeStarted=$_.TimeStarted.ToLocalTime()
$FormatTimeStarted=$TimeStarted.ToString("dd/MM/yyyy HH:mm:ss")

Convert UNIX epoch time

Note: If you use ToString instead of ToLocalTime on the end it will show UTC time.

Sometimes you'll see dates/times stored like this: 1681420901. This is how UNIX calculates time. It's a 10-digit number representing how many seconds have elapsed since January 1, 1970. If you need to convert, do this:

(([System.DateTimeOffset]::FromUnixTimeSeconds('1681420901')).DateTime).ToLocalTime()

Convert string to date and time

Note: You need to be careful how you format yyyyMMddHHmmss.

[DateTime]::ParseExact('20230414132141', 'yyyyMMddHHmmss', $null)

Exchange

Health sets

Get unhealthy Health Sets from a server

get-healthreport -Server EXCH_SERVER | where {$_.alertvalue -eq "unhealthy"} | sort HealthSet | ft HealthSet, AlertValue

Send email

To send email from scripts

$EmailFromAddress="from_address"
$EmailToAddress="your_address"
$EmailServer="your_email_server"
$EmailPort="25"

Another way, not sure it works...

$SmtpClient = New-Object System.Net.Mail.SmtpClient
$SmtpServer = "smtp.server.address"
$SmtpClient.host = $SmtpServer
$From = "Email Test <emailtest@domain.com>"
$To = "recipient@domain.com"
$Title = "Subject"
$Body = "Body Text"
$SmtpClient.Send($From, $To, $Title, $Body)

Event logs

Clear event log

Clear-EventLog -LogName "Operations Manager"

Search event log description

This is ugly but it's the only way I've found to scrape out info you're looking for in events. In this example, I needed to find the users connecting to SCOM.

  • First get the events you need and output to the clipboard:

Get-EventLog -LogName "Operations Manager" -Source "OpsMgr SDK Service" | Where-Object {$_.EventID -eq 26328} | select -ExpandProperty message | clip

  • Paste into a text file then run this:

$a=gc C:\temp\file.txt
$a | select-string -Pattern "USER_NAME" | clip

Then paste that into Excel and off you go.

Search for ID

Get-EventLog -LogName Application -Source "Directory Synchronization" | Where-Object {$_.EventID -eq 106}

Search for ID and return top 5 events

Get-EventLog -LogName "Operations Manager" -Source "HealthService" | Where-Object {$_.EventID -eq 7002} | select -ExpandProperty message -First 1

Write event

Write-EventLog -LogName "Operations Manager" -Source "Health Service Script" -EventId 17611 -EntryType Error -Message "test" -Category 0

Files and Folders

Find files

This will search from the root of e: drive for a file

gci -Path e:\ -Filter FILE_NAME -Recurse | sort Directory | select Directory

Rename file

Rename-Item C:\temp\file.txt new_name.txt

Misc

Create array

$Array=@(item1, item2, item3)

And Or examples

If (!$match -eq $true -and $Param2 -eq "Pending") {
$Global:Marker="GOOD"
$Global:Result+="$Param3`:'$Param2' "
}

Or...

If (!$match -eq $true -or $Param2 -eq "Pending") {
$Global:Marker="BAD"
$Global:Result+="$Param3`:'$Param2' "
}

Check variable is an array

$your_variable -is[array]

Get cmdlets for a module

Get-Command -Module OperationsManager

Get-Command -Module OperationsManager -CommandType cmdlet

Get-Command -Module Citrix.Broker.Commands

Regex testing

I'm don't think regex in PowerShell cares about case because this is a match:

'jump' -match '(JUMP)'

Case-insensitive and must start with the string jump or sql.

'jump' -match '(?i:^jump) | (?i:^sql)'

Generate GUID

Generate a single GUID

[guid]::NewGuid().ToString("N")

Generate x number of GUIDs

1..5 | % {[guid]::NewGuid().ToString("N")}

Format current time

You can assign this to a variable and it will work in quotes.

Get-Date -format yyyyMMddHHmmss

Ping

Ping computers from file

$erroractionpreference=continue
$a=gc C:\temp\file.txt
foreach ($i in $a) {
try {
If (Test-Connection -computername $i -Count 2 -quiet) {
"$i^YES"} ELSE {
"$i^NO"
}}
catch {
"$i^PROBLEM"
}}

Ports

Check port is open

Only works for TCP ports.

Test-NetConnection -ComputerName COMPUTER_NAME -Port 5723 -InformationLevel "Detailed"

Processes

Get a process

Get-Process notepad*

Stop a process

Stop-Process -name notepad -Force

Registry

Get string value data

Some examples. I've used the top two in SCOM discoveries.

get-childitem -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" | Get-ItemProperty | sort displayname | ft displayname, DisplayVersion

get-childitem -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" | Get-ItemProperty | sort displayname | ft displayname, DisplayVersion

(Get-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Network Associates\TVD\Shared Components\Framework').LastASCI

Get string value data from remote computer

Note: Invoke-Command can be slow.

Invoke-Command -ComputerName COMPUTER_NAME  {(Get-ItemProperty -Path 'HKLM:\software\Wow6432Node\Network Associates\ePolicy Orchestrator').InstallFolder}

Check if value exists

This returns true or false if a reg value exists. Pass in params in red.

Note: This doesn't check for the value data.

Function Test-RegistryValue ($regkey, $name) {
if (Get-ItemProperty -Path $regkey -Name $name -ErrorAction Ignore) {
$true
} else {
$false
}}
Test-RegistryValue "HKLM:\SOFTWARE\WOW6432Node\Network Associates\ePolicy Orchestrator\Application Plugins\EPOAGENT3000\" "Version"

SCOM

Agents

Get agents connected to specific Management server

(Get-SCOMManagementServer -Name MS_NAME).GetAgentManagedComputers() | sort DisplayName | ft DisplayName

Get agents connected to specific Gateway server

(Get-SCOMGatewayManagementServer -Name GW_NAME).GetAgentManagedComputers() | sort DisplayName | ft DisplayName

Approve all pending Windows agents

The PassThru parameter shows the output.

Get-SCOMPendingManagement | Approve-SCOMPendingManagement -PassThru

Search pending queue for an agent

Get-SCOMPendingManagement | where {$_.AgentName -match " COMPUTER_NAME"} | sort AgentName | ft AgentName

Search for an agent

Get-SCOMAgent -Name *COMPUTER_NAME* | Sort DisplayName | ft DisplayName -au

Get grey agents one-liner

This is a work-in-progress. I want to end up with a one-liner that gets all unhealthy agents no matter what dodgy state they're in, i.e. showing healthy but it's grey.

get-scomclass -name "Microsoft.SystemCenter.HealthService" | get-scomclassinstance | where {$_.IsAvailable -eq $false -and $_.InMaintenanceMode -eq $false} | sort DisplayName | ft DisplayName, HealthState, InMaintenanceMode, IsAvailable

Get grey agents and write output to screen and file

$output="C:\temp\GreyHealthService.csv"
$date= Get-Date
Write-Host
Write-Host "Script start: $date"
Write-Host
$green=0
$red=0
$csv+="Ping,FQDN,ComputerName,DomainName`r"
$Class=get-scomclass -name "Microsoft.SystemCenter.HealthService"
$Instance=get-scomclassinstance -class $Class | where { $_.IsAvailable -eq $false -and $_.InMaintenanceMode -eq $false} | sort DisplayName
Write-Host -ForegroundColor yellow "Getting broken (grey) health services."
Write-Host
$CountGrey = $Instance | Measure-Object
If ($CountGrey.count -gt 0) {
foreach ($x in $Instance) {
<#
Added this line, this article explains why.
#>
If ($x.HealthState -eq "Success")
{
$fqdn = $x.DisplayName
$compname=$fqdn.split("{.}", 2)[0]
$domname=$fqdn.split("{.}", 2)[1]
$count = $count + 1
If (Test-Connection -computername $fqdn -Count 2 -quiet) {
$Green+=1
$csv+="Up,$fqdn,$compname,$domname`r"
Write-Host -ForegroundColor green "Up,$fqdn,$compname,$domname"
}
Else {
$Red+=1
$csv+="Down,$fqdn,$compname,$domname`r"
Write-Host -ForegroundColor red "Down,$fqdn,$compname,$domname"
}
}
} # end for
write-host
write-host -ForegroundColor yellow "Total:" ($Green + $Red)
write-host -ForegroundColor green "Green: $Green"
write-host -ForegroundColor red "Red: $Red"
write-host "Exporting output to $output"
$csv | out-file $output
write-host
} Else {
write-host -ForegroundColor green "No grey agents"
Write-Host
}
$date= Get-Date
Write-Host "Script finish: $date"
Write-Host

Enable proxy on all agents in SCOM 2016

Change localhost to FQDN of a management server if doing remotely.

To see current settings:

Add-PSSnapin "Microsoft.EnterpriseManagement.OperationsManager.Client";
New-ManagementGroupConnection -ConnectionString:localhost;
Set-Location "OperationsManagerMonitoring::";
Get-DefaultSetting | where {$_.Name -eq "HealthService\ProxyingEnabled"} | ft -a Name, Value

Or run this to see all settings:

Get-DefaultSetting | Sort Name | ft Name, Value -au

To enable proxy on all agents:

Add-PSSnapin "Microsoft.EnterpriseManagement.OperationsManager.Client";
New-ManagementGroupConnection -ConnectionString:localhost;
Set-Location "OperationsManagerMonitoring::";
Set-DefaultSetting -Name HealthService\ProxyingEnabled -Value True

Install SCOM agent

The below command will work for most environments, it will:
  • Disable AD integration
  • Disable Error Report forwarding
  • Use local system account
  • Not install .NET Application Performance Monitoring. If you want to install APM set NOAPM=0

msiexec.exe /i MOMAgent.msi /qb /l* %temp%\MOMAgentinstall.log USE_SETTINGS_FROM_AD=0 MANAGEMENT_GROUP=MGMT_GROUP_NAME MANAGEMENT_SERVER_DNS=MS_FQDN  ENABLE_ERROR_REPORTING=0 ACTIONS_USE_COMPUTER_ACCOUNT=1 USE_MANUALLY_SPECIFIED_SETTINGS=1 NOAPM=1 AcceptEndUserLicenseAgreement=1

Get count of agents connected to management servers and gateway servers

This only shows Windows agents. It doesn't get UNIX/Linux agents which connect to a resource pool.

$Output=""
$a=Get-SCOMManagementServer | sort displayname
$a | % {
$IsGateway=$_.IsGateway
$Name=$_.displayname
$Count=((Get-SCOMManagementServer -Name $Name).GetAgentManagedComputers()).count
If ($IsGateway -eq $true) {
$Role="Gateway Server"
} else {
$Role="Management Server"
}
$Output+="$Role - $Name - $Count`n"
}
$Output

Alerts

It’s faster using criteria than a where clause. Operators are similar to SQL so you can use < > , % , ! = etc.

(0 = Information, 1=Warning, 2=Error/Critical)

Close alerts with healthy monitor

get-scomalert -Criteria "ResolutionState!=255 AND MonitoringObjectHealthState='1' AND IsMonitorAlert='$true'" | Resolve-SCOMAlert -Comment "Monitor healthy."

Close alert by name

get-scomalert -Criteria "ResolutionState!='255' and Name='Cmdb script warning'" | Resolve-SCOMAlert -Comment "Not needed."

Close multiple alerts by name

get-scomalert -Criteria "ResolutionState != 255 and Name='PowerShell Script Problem' or Name='Cmdb script warning'" | Resolve-SCOMAlert -Comment "Not needed."

Close rule alert based on owner

get-scomalert -Criteria "ResolutionState != 255 and IsMonitorAlert='false' and Owner='OWNER'" | Resolve-SCOMAlert -Comment "Not needed."

Close alert date math

get-scomalert -Criteria "ResolutionState!='255' and Name='Commvault Alert (Critical)' and TimeRaised < '$((get-date).addDays(-1))'" | Resolve-SCOMAlert -Comment "Not needed."

get-scomalert -Criteria "ResolutionState!='255' and Name='IntelliSnap for NetApp Alert (Critical)' and TimeRaised < '$((get-date).addDays(-1))'" | Resolve-SCOMAlert -Comment "Not needed."

get-scomalert -Criteria "ResolutionState!='255' and Name='Power Shell Script failed to run' and TimeRaised < '$((get-date).addDays(-1))'" | Resolve-SCOMAlert -Comment "Not needed."

get-scomalert -Criteria "ResolutionState!='255' and Name='Operations Manager failed to run a WMI query' and TimeRaised < '$((get-date).addDays(-1))'" | Resolve-SCOMAlert -Comment "Not needed."

Close rule alerts

get-scomalert -Criteria "ResolutionState!='255' and IsMonitorAlert!='$true'" | Resolve-SCOMAlert -Comment "Not needed."

Close alerts in maintenance mode

get-scomalert -Criteria "ResolutionState!='255' and MonitoringObjectInMaintenanceMode='true'" | Resolve-SCOMAlert -Comment "Object in maintenance mode."

Get alert name from monitor display name

If you get this error, it's (likely) because the monitor doesn't generate an alert by default:

Exception calling "GetStringResource" with "1" argument(s): "The object passed to the ManagementPackElementReference constructor is not valid."

$Monitor=get-scommonitor -DisplayName "NAME"
$AlertSettings=$Monitor.AlertSettings
$AlertName= $AlertSettings.AlertMessage.Identifier.Path
$MP=$Monitor.GetManagementPack()
$AlertDisplayName=$MP.GetStringResource($AlertName).DisplayName    
$AlertDisplayName

Get active alerts by owner

get-scomalert -Criteria "ResolutionState!=255 AND Owner='NAME'"

Get active alerts with healthy monitor

This is the opposite of this.

Note: For MonitoringObjectHealthState it's: 0 = Error, 1 = Success, 2 = Warning.

get-scomalert -Criteria "ResolutionState!=255 AND MonitoringObjectHealthState='1' AND IsMonitorAlert='$true'"

Get closed alerts with wildcard

get-scomalert -Criteria "ResolutionState = 255 and Name LIKE 'Carbon%'"

Get active alerts by name

get-scomalert -Criteria "ResolutionState != 255 and Name='Power Shell Script failed to run'"

Get active alert count and group by name

get-scomalert -Criteria "ResolutionState!='255'" | group Name | sort count -desc | ft name, count

Get active alerts with wildcard by name and export to csv

Get-SCOMAlert -Criteria "ResolutionState != 255 and Name like '%mcafee%'" | select timeraised, name, PrincipalName | sort timeraised| Export-Csv McAfee_alerts.csv -NoTypeInformation

Get active Trellix alerts and export to csv

This uses the ^ separator instead of Export-Csv cmdlet because it formats it better.

$count=0
$displayname=""
$file=""
$file+="SERVER^ALERT^DESCRIPTION`r"
$a=get-scomalert -Criteria "ResolutionState != 255 and Name like'trellix%'" | sort MonitoringObjectDisplayName
$output="C:\temp\Alerts.csv"
$total=$a.count
foreach ($i in $a) {
$count=$count+1
write-host -foregroundcolor yellow "$count/$total $i"
$displayname=$i.MonitoringObjectDisplayName
$name=$i.name
$description=$i.description
write-host "$i^$displayname^$name^$description"
$file+="$displayname^$name^$description`r"
}
write-host -foregroundcolor yellow "Exporting output to $output"
$file | out-file $output

Get active alerts by custom field

get-scomalert -Criteria "ResolutionState!=255 AND CustomField1='DNS'"

Get active alerts by name with wildcard

get-scomalert -Criteria "ResolutionState!=255 AND Name LIKE '%IIS%'"

Get active alerts generated by rules

get-scomalert -Criteria "ResolutionState != 255 and IsMonitorAlert='false'"

Get active alerts by priority

get-scomalert -Criteria "ResolutionState != 255 and Priority = '0'" | ft name, Priority

Get active alerts by severity

get-scomalert -Criteria "ResolutionState != 255 and Severity = '2'" | ft name, Severity

Get alerts with ResolutionState=New, Severity=Error, Priority=High

Get-SCOMAlert -Criteria "ResolutionState='0' AND Severity = 2 AND Priority = 2" | Sort TimeRaised -Descending | ft TimeRaised, severity, priority, ResolutionState -au

Get alerts with ResolutionState=New, Severity=Error or Warning, Priority=Medium or High

Get-SCOMAlert -Criteria "ResolutionState='0' AND Severity>=1 AND Priority>=1" | Sort TimeRaised -Descending | ft TimeRaised, severity, priority, ResolutionState -au

Same as above command but notice the highlighted operators are different

Get-SCOMAlert -Criteria "ResolutionState='0' AND Severity!=0 AND Priority!=0" | Sort TimeRaised -Descending | ft TimeRaised, severity, priority, ResolutionState -au

Get open alerts created in the last 24 hours

Get-SCOMAlert -Criteria "ResolutionState!='255' AND TimeRaised > '$((get-date).addDays(-1))'" | Sort TimeRaised -Descending | ft TimeRaised, Name, Id -au

Get open 'Health Service Heartbeat Failure' alerts

Get-SCOMAlert -Criteria "ResolutionState!='255' AND Name='Health Service Heartbeat Failure'" | Sort  TimeRaised -Descending  | ft TimeAdded, MonitoringObjectDisplayName -au

Set assigned alerts back to new

get-scomalert -Criteria "ResolutionState='1'" | Set-SCOMAlert -Owner "" -CustomField1 "" -CustomField2 "" -ResolutionState 0

Classes

This section now includes note properties.

This one is handy to keep at the top. It reads in a list of computers then gets the instance ID of a class, if a match is found it returns the ID and DisplayName. It's handy when you need to add a bunch of overrides manually to an .xml file. Change class as needed.

$class="Microsoft.Intune.ConfigurationManager.Class.ServerSeed"
$instances=get-scomclass -name $class | get-scomclassinstance | sort displayname | select displayname, id
$file=gc "C:\temp\file.txt" | sort
write-host -foreground yellow "Getting instance IDs for class $class."
foreach ($i in $instances) {
$match=select-string -inputobject $file $i.displayname -quiet
if ($match -eq $true) {
$displayname= $i.displayname
$id=$i.id
"$id ^ $displayname"
}}

ADFS servers

This just gets 2012 ADFS servers.

Get-SCOMClass -name Microsoft.ActiveDirectoryFederationServices2012R2.FederationServer | Get-SCOMClassInstance | sort path | ft path

Agents

Windows agent FQDN

Get-SCOMClass -name Microsoft.SystemCenter.Agent | Get-SCOMClassInstance | sort path | ft path

Windows agent versions

get-scomclass -name "Microsoft.SCOM.UpdateRollup.Class.WindowsComputer" | get-scomclassinstance | sort displayname | % {$_.displayname + "^" + $_."[Microsoft.SCOM.UpdateRollup.Class.WindowsComputer].AgentVersion".value}

Windows agents with more than one management group

[int]$count=""
$a=get-scomclass -name "Microsoft.SCOM.UpdateRollup.Class.WindowsComputer" | get-scomclassinstance | sort
$a | % {
$MgCount=$_."[Microsoft.SCOM.UpdateRollup.Class.WindowsComputer].AgentMGCount".value
if (($MgCount -gt 1) -and ($MgCount -ne "n/a")) {
$count+=1
"$_, $MgCount"
}}
write-host "Count: $count"

Windows agents - unique short and long domain names

This works but could be done better.

$a=@()
$b=get-scomclass -name Microsoft.Windows.Computer | Get-SCOMClassInstance
foreach ($i in $b) {
$a+=$i."[Microsoft.Windows.Computer].NetbiosDomainName".value + "," + $i."[Microsoft.Windows.Computer].DomainDnsName".value #+ "`n"
}
$a | sort | Get-Unique

Certificates

Get computer name and thumbprint from file

I use this when I need to disable certificate monitoring. It extracts the computer name and thumbprint required for the override.

$Output=""
$a=gc C:\Temp\file.txt
foreach ($i in $a) {
$b=get-scomclass -name Certificate.Class.WindowsCertificate | get-scomclassinstance | where {$_.path -eq $i} | select path, name
foreach ($c in $b) {
$Computer=$c.path
$Thumbprint=$c.name
$Output+="$Computer^$Thumbprint`n"
}
}
$Output

Get all certificate info

get-scomclass -name Certificate.Class.WindowsCertificate | get-scomclassinstance | sort name | % {$_.name + "^" + $_.path + "^" + $_."[Certificate.Class.WindowsCertificate].IssuedTo".value + "^" + $_."[Certificate.Class.WindowsCertificate].NotBefore".value + "^" + $_."[Certificate.Class.WindowsCertificate].NotAfter".value}

Filter on IssuedTo property

get-scomclass -name Certificate.Class.WindowsCertificate | get-scomclassinstance | where {$_."[Certificate.Class.WindowsCertificate].IssuedTo".value -eq "Windows Azure CRP Certificate Generator"} | sort path | % {$_.path + "^" + $_.name + "^" + $_."[Certificate.Class.WindowsCertificate].IssuedTo".value}

Citrix NetScaler IP address

get-scomclass -DisplayName "citrix netscaler appliance" | get-scomclassinstance | % {$_.displayname + " - " + $_."[ComTrade.Citrix.NetScaler.Appliance].IPAddress".value}

Config Manager

Servers (running any role)

These only work for the Microsoft 2012 mps. Remember I wrote my own mp here.

get-scomclass -name Microsoft.SystemCenter2012.ConfigurationManager.Server | get-scomclassinstance | sort DisplayName | ft path

Sites

get-scomclass -name "Microsoft.SystemCenter2012.ConfigurationManager.Site" | get-scomclassinstance | sort displayname | % {
$SiteName=$_."[Microsoft.SystemCenter2012.ConfigurationManager.Site].SiteName".value
$SiteServer=$_.name
$Version=$_."[Microsoft.SystemCenter2012.ConfigurationManager.Site].Version".value
$SiteCode=$_."[Microsoft.SystemCenter2012.ConfigurationManager.Site].SiteCode".value
$SiteTypeName=$_."[Microsoft.SystemCenter2012.ConfigurationManager.Site].SiteTypeName".value
$ParentSiteCode=$_."[Microsoft.SystemCenter2012.ConfigurationManager.Site].ParentSiteCode".value
$Domain=$_."[Microsoft.SystemCenter2012.ConfigurationManager.Site].Domain".value
$HierarchyId=$_."[Microsoft.SystemCenter2012.ConfigurationManager.Site].HierarchyId".value
$SiteType=$_."[Microsoft.SystemCenter2012.ConfigurationManager.Site].SiteType".value
$SiteName + "^" + $SiteServer + "^" + $Version + "^" + $SiteCode + "^" + $SiteTypeName + "^" + $ParentSiteCode + "^" + $Domain + "^" + $HierarchyId + "^" + $SiteType
}

Distribution points

get-scomclass -name Microsoft.SystemCenter2012.ConfigurationManager.DistributionPoint | get-scomclassinstance | sort DisplayName | ft path

Management points

get-scomclass -name Microsoft.SystemCenter2012.ConfigurationManager.ManagementPoint | get-scomclassinstance | sort DisplayName | ft path

Service Connection points

get-scomclass -name Microsoft.SystemCenter2012.ConfigurationManager.ServiceConnectionPoint | get-scomclassinstance | sort DisplayName | ft path

Sofware Update points

get-scomclass -name Microsoft.SystemCenter2012.ConfigurationManager.SoftwareUpdatePoint | get-scomclassinstance | sort DisplayName | ft path

Reporting services points

get-scomclass -name Microsoft.SystemCenter2012.ConfigurationManager.SrsReportingPoint | get-scomclassinstance | sort DisplayName | ft path

Clients

get-scomclass -name Microsoft.SystemCenter2012.ConfigurationManager.Client | get-scomclassinstance | sort DisplayName | ft path

DHCP servers

get-scomclass -name Microsoft.Windows.DHCPServer.Library.Server | Get-SCOMClassInstance | sort path | select path

DHCP Operating Systems

get-scomclass -name "Microsoft.Windows.DHCPServer.Library.Server" | get-scomclassinstance | sort displayname | % {$_.displayname + "," + $_.id + "," + $_."[Microsoft.Windows.DHCPServer.Library.Server].OSCurrentVersion".value}

DNS servers

This won't return all versions of DNS servers, it only seems to return 2012/R2 versions:

get-scomclass -name Microsoft.Windows.Server.DNS.Server | Get-SCOMClassInstance | sort path | select path

This will get 2016 versions...

get-scomclass -name Microsoft.Windows.DNSServer.2016.Server | Get-SCOMClassInstance | select path

DNS zones (Server 2016)

Note the sort by bit.

get-scomclass -name "Microsoft.Windows.DNSServer.2016.Zone" | get-scomclassinstance | sort displayname, "[Microsoft.Windows.DNSServer.2016.Zone].HostName" | % {$_."[Microsoft.Windows.DNSServer.2016.Zone].HostName".value + "^" + $_."[Microsoft.Windows.DNSServer.2016.Zone].ZoneName".value}

Domain Controllers

get-scomclass -name Microsoft.Windows.Server.AD.Library.DomainControllerRole | Get-SCOMClassInstance | sort path | ft path

Exchange servers

get-scomclass -Name Microsoft.Exchange.15.Server | Get-SCOMClassInstance | sort name | ft path

Health Service

This is the best way to get a list of all Windows computers in your environment. It matches with what's in the console for agents, gateways and management servers. It will not show virtual names from clusters.

Get-SCOMClass -name Microsoft.SystemCenter.HealthService | Get-SCOMClassInstance | sort path | ft path

IIS servers

get-scomclass -name Microsoft.Windows.InternetInformationServices.ServerRole | Get-SCOMClassInstance | sort path | ft path

Operating System

get-scomclass -name Microsoft.Windows.OperatingSystem | get-scomclassinstance | sort path | % {$_.Path + "^" + $_."[Microsoft.Windows.OperatingSystem].OSVersionDisplayName".value}

Or...

$OS = get-scomclass -name Microsoft.Windows.OperatingSystem | get-scomclassinstance | sort path | Select-Object -Property Path, @{n="OS"; e={$_."[Microsoft.Windows.OperatingSystem].OSVersionDisplayName".value}}

PDC emulators

This is just for 2016 DCs.

$a=get-scomclass -name "Microsoft.Windows.Server.2016.AD.DomainControllerRole" | get-scomclassinstance | sort
$b= @()
$a | % {
$b+=$_."[Microsoft.Windows.Server.AD.Library.DomainControllerRole].PDCEmulator".value
}
$c=$b | group | sort name | select name
$c

SharePoint servers

get-scomclass -Name Microsoft.SharePoint.SPServer | Get-SCOMClassInstance | sort path | ft path

SQL

Servers

I think this works. It's tricky getting servers names from SQL so double-check first.

get-scomclass -name Microsoft.SQLServer.Windows.DBEngine | get-scomclassinstance | % {$_."[Microsoft.SQLServer.Windows.DBEngine].PrincipalName".value} | sort

Get SQL instance name and other info

get-scomclass -displayname "MSSQL on Windows: DB Engine" | get-scomclassinstance | sort displayname | % {$_."[Microsoft.SQLServer.Core.DBEngine].InstanceName".value + "^" + $_."[Microsoft.SQLServer.Windows.DBEngine].PrincipalName".value + "^" + $_."[Microsoft.SQLServer.Core.DBEngine].Edition".value + "^" + $_."[Microsoft.SQLServer.Core.DBEngine].Version".value + "^" + $_."[Microsoft.SQLServer.Windows.DBEngine].Account".value + "^" + $_."[Microsoft.SQLServer.Core.DBEngine].Cluster".value}

Trellix versions and group them

get-scomclass -name Trellix.Class.Agent | get-scomclassinstance | % {$_."[Trellix.Class.Agent].Version".value} | group "[Trellix.Class.Agent].Version".value | sort count -desc | ft name, count

Failovers

Get failovers for an agent or gateway

$Failover=""
$Computer = Get-SCOMagent -Name "AGENT_FQDN"
# $Computer = Get-SCOMManagementServer -Name "GW_FQDN"
$Primary="(P)"+$Computer.GetPrimaryManagementServer().name
$Failovers=$Computer.GetFailoverManagementServers()
foreach ($i in $Failovers) {
$Failover+="(F)"+$i.principalname + "`n"
}
$Primary,$Failover

Get failovers for all agents & gateways and write to file

This gets the primary and failover servers for agents and gateways and writes the output to screen and file.

[int]$count="" # need to declare at int or $count gets weird.
$item=""
$fqdn=""
$pri=""
$file=""
$fail=""
$arr=@("Agent", "Gateway")
$file+="TYPE^FQDN^PRIMARY_MS^FAIL_1^FAIL_2^FAIL_3`r"
$output="C:\temp\FailoverConfig.csv"
foreach ($item in $arr) {
if ($item -eq "Agent") {
<#
Use this for testing, otherwise script will get everything.
$Type=Get-SCOMAgent | where {$_.PrincipalName -match "domain.name"} | sort PrincipalName | select -First 20
#>
$Type=Get-SCOMAgent | sort PrincipalName
} elseif ($item -eq "Gateway") {
$Type=Get-SCOMManagementServer | where {$_.IsGateway -eq $true} | sort PrincipalName
}
$Type | sort name | foreach {
$count+=1
$fqdn=$_.PrincipalName
$pri=($_.GetPrimaryManagementServer()).PrincipalName
$failovers=$_.GetFailoverManagementServers()
foreach ($i in $failovers) {
$fail+=$i.principalname + "^"
}
$file+="$item^$fqdn^$pri^$fail`r"
Write-Host "$count^$item^$fqdn^$pri^$fail"
# Need to reset these.
$fqdn=""
$pri=""
$fail=""
}}
write-host "Exporting output to $output"
$file | out-file $output

Set failovers for an agent

The If statement is intended to skip computers that are in MM or not healthy i.e., showing as Uninitialized. 

$Agent=Get-SCOMagent -Name "COMPUTER_NAME"
$PrimaryServer=Get-SCOMManagementServer -Name "MS_FQDN"
$FailoverServer=Get-SCOMManagementServer -Name "MS_FQDN"
$Computer=$Agent.DisplayName
$HealthState=$Agent.HealthState
If ($HealthState -eq "Uninitialized") {
write-host -foregroundcolor yellow "$Computer health state is uninitialized, skipping failover setup."
} else {
write-host -foregroundcolor green "Setting up failovers on $Computer"
# Set-SCOMParentManagementServer -Agent $Agent -FailoverServer  $null 
# Might need to add this

Set-SCOMParentManagementServer -Agent $Agent -PrimaryServer $PrimaryServer
Set-SCOMParentManagementServer -Agent $Agent -FailoverServer $FailoverServer
}

Set failovers for multiple agents from file

$a=gc C:\temp\file.txt
foreach ($b in $a) {
$Agent = Get-SCOMagent -Name $b
$PrimaryServer = Get-SCOMManagementServer -Name "MS_FQDN"
$FailoverServer = Get-SCOMManagementServer -Name "MS_FQDN"
$Computer=$Agent.DisplayName
$HealthState=$Agent.HealthState
If ($HealthState -eq "Uninitialized") {
write-host -foregroundcolor yellow "$Computer health state is uninitialized, skipping failover setup."
} else {
write-host -foregroundcolor green "Setting up failovers on $Computer"
# Set-SCOMParentManagementServer -Agent $Agent -FailoverServer $null  # Might need to add this
Set-SCOMParentManagementServer -Agent $Agent -PrimaryServer $PrimaryServer
Set-SCOMParentManagementServer -Agent $Agent -FailoverServer $FailoverServer
}}

Set failovers for a gateway

$Gateway = Get-SCOMManagementServer -Name "GW_FQDN"
$PrimaryServer = Get-SCOMManagementServer -Name "MS_FQDN"
$FailoverServer = Get-SCOMManagementServer -Name "MS_FQDN"
$Computer=$Gateway.DisplayName
$HealthState=$Gateway.HealthState
If ($HealthState -eq "Uninitialized") {
write-host -foregroundcolor yellow "$Computer health state is uninitialized, skipping failover setup."
} else {
write-host -foregroundcolor green "Setting up failovers on $Computer"
Set-SCOMParentManagementServer -GatewayServer $Gateway -FailoverServer $null
Set-SCOMParentManagementServer -GatewayServer $Gateway -PrimaryServer $PrimaryServer
Set-SCOMParentManagementServer -GatewayServer $Gateway -FailoverServer $FailoverServer
}

Gateways

Get-SCOMGatewayManagementServer | sort DisplayName | ft DisplayName, IPAddress

Groups

Get group members (and class type)

This could be improved but it's a start.

(get-scomgroup -DisplayName "TestB CMDB Windows Server Catc").GetRelatedMonitoringObjects() | sort displayname | ft displayname, fullname

Get group name and displayname

Get-SCOMGroup | where {$_.DisplayName -like "*cmdb*"} | sort DisplayName | ft DisplayName, FullName

Get group properties

get-scomgroup -DisplayName *cmdb* | sort DisplayName | ft DisplayName, fullname, id

Get count of group members

(get-scomgroup -DisplayName "SQL Availability Group Primary Databases" | Get-SCOMClassInstance).count

Get SQL servers

get-scomgroup -displayName "MSSQL on Windows: SQL Server Computers" | get-scomclassinstance | sort DisplayName | select DisplayName

Get nested group members

This works but could be improved.

Function Get-SCOMGroupMembers($group) {
$group= Get-SCOMGroup -DisplayName $group
write-host -foregroundcolor yellow "Group name:" $group.DisplayName
$group | Get-SCOMClassInstance | % {
if (($_ | Get-SCOMGroup) -ne $null) {
Get-SCOMGroupMembers $_ | select FullName -expandproperty FullName # Using FullName so you can see classes.
} else {
$_
}}}
Get-SCOMGroupMembers "GROUP_NAME"

Maintenance mode

Get Windows agents maintenance mode status from file

$a=@(get-scomclass -name Microsoft.SystemCenter.HealthService | Get-SCOMClassInstance | sort | where {$_.InMaintenanceMode -eq $true})
$b=@(gc C:\temp\file.txt) # add computers to check
foreach ($i in $b) {
$match=select-string -inputobject $i $a -quiet
if ($match -eq $true) {
write-host -foregroundcolor red "$i - In MM"
} else {
write-host -foregroundcolor green "$i - Not in MM"
}}

Get start/end time of all Windows agents in maintenance mode

$b=@()
$a=get-scomclass -name Microsoft.Windows.Computer | Get-SCOMClassInstance | sort | where {$_.InMaintenanceMode -eq $true}
foreach ($i in $a) {
$b+=$i.GetMaintenanceWindow() | select -property @{Name="Server";Expression={$i}}, User, StartTime, ScheduledEndTime, Reason, Comments
}
$b | ft

Get count of Windows agents in maintenance mode

(get-scomclass -name Microsoft.SystemCenter.HealthService | Get-SCOMClassInstance | where {$_.InMaintenanceMode -eq $true}).count

Stop maintenance mode on multiple Windows computers from file

$a=gc "C:\temp\file.txt"
foreach ($i in $a) {
write-host "Stopping maintenance mode on $i"
(Get-SCOMClass -Name microsoft.windows.computer | Get-SCOMClassInstance | where {$_.displayname -eq $i}).StopMaintenanceMode([datetime]::Now.ToUniversalTime())
}

Management packs

Get classes

(Get-SCOMManagementPack -Name Tenable.Nessus.Monitoring).GetClasses() | sort name | ft name

Get discoveries

(Get-SCOMManagementPack -Name Tenable.Nessus.Monitoring).GetDiscoveries() | sort name | ft name

Get module types

(Get-SCOMManagementPack -Name Tenable.Nessus.Monitoring).GetModuleTypes() | sort name | ft name

Get unit monitor types

(Get-SCOMManagementPack -Name Tenable.Nessus.Monitoring).GetUnitMonitorTypes() | sort name | ft name

Get monitors

(Get-SCOMManagementPack -Name Tenable.Nessus.Monitoring).GetMonitors() | sort name | ft name

Get recoveries

(Get-SCOMManagementPack -Name Tenable.Nessus.Monitoring).GetRecoveries() | sort name | ft name

Remove management packs

If the mp has dependencies it will throw an error, just keep re-running it until they're all gone.

$a = gc C:\temp\file.txt
foreach ($i in $a) {
If (Get-SCOMManagementPack -name $i) {
write-host -foregroundcolor green "Removing Mp: $i"
Get-SCOMManagementPack -name $i | Remove-SCOMManagementPack
}
else {
write-host -foregroundcolor yellow "Mp not found: $i"
}
}

Export all unsealed mps

Get-SCOMManagementPack | where {$_.Sealed -eq $false} | Export-SCOMManagementPack -Path D:\MP\Unsealed

Export all sealed mps

Don't know why you'd do this but here it is.

Get-SCOMManagementPack | where {$_.Sealed -eq $true} | Export-SCOMManagementPack -Path  D:\MP\Unsealed

Export list of mps in a file to a folder

$a=gc C:\Temp\file.txt
foreach ($i in $a) {Get-SCOMManagementPack -Name $i | Export-SCOMManagementPack -Path C:\Build\MP\Overrides\CmdbOverrides}

Get sealed mps

Get-SCOMManagementPack | where {$_.Sealed -eq $true} | ft name

Get unsealed mps 

Get-SCOMManagementPack | where {$_.Sealed -ne $true} | ft name

Get unsealed with a name

Get-SCOMManagementPack -Name *cluster*.overrides | where {$_.Sealed -ne $true} | ft name

Get management pack dependencies

This will get dependent mps for a single mp.

$AllManagementPacks = Get-SCOMManagementPack
$MPToFind = $AllManagementPacks | where{$_.Name -eq "MP_NAME"}
$DependentMPs = @()
foreach($MP in $AllManagementPacks) {
$Dependent = $false
$MP.References | foreach{
if($_.Value.Name -eq $MPToFind.Name) {$Dependent = $true}
}
if($Dependent -eq $true) {
$DependentMPs+= $MP
}}
$DependentMPs | ft Name

Unbundles .mpb files to .xml files

Get-SCOMManagementPack -BundleFile Microsoft.Windows.HyperV.Library.mpb | Export-SCOMManagementPack -Path

Management servers

Get-SCOMManagementServer | where {$_.IsGateway -eq $false} | sort DisplayName | ft DisplayName, IPAddress, IsRootManagementServer

Monitors

Get monitor target class

This shows the display name for a class that a monitor targets, and the mp the class is in. This applies to rules too.

(Get-SCOMMonitor -DisplayName "Computer Not Reachable").target.id | get-scomclass | ft DisplayName, ManagementPackName

Get monitor target class from file

Similar to above but for a list of monitor names in a file. It doesn't show the class mp. 

$a=gc C:\temp\file.txt
foreach ($i in $a) {
$b=Get-SCOMMonitor -name $i
$c=$b.Target.Identifier.Path
$d=get-scomclass -name $c
$d.displayname
}

Get web monitors

This matches what is in Authoring > Management Pack Templates > Web Application Availability Monitoring.

get-scomclass -name Microsoft.SystemCenter.WebApplicationSolutions.SingleUrlTest | Get-SCOMClassInstance | sort displayname | ft DisplayName

This matches what is in Monitoring > Application Monitoring > Web Application Availability Monitoring > Test State.

get-scomclass -Name Microsoft.SystemCenter.WebApplicationTest.WebTest | Get-SCOMClassInstance | sort | ft DisplayName

Get monitors in an mp

The HasNonCategoryOverride property means (usually) that there's an override within the mp.

Get-SCOMManagementPack -name Microsoft.Windows.Server.2016.Monitoring | Get-SCOMMonitor | sort Enabled | ft name, Enabled, HasNonCategoryOverride

Reset monitor

This reads in a list of computers and resets the monitor you specify. This usually happens when someone has closed the alert without the issue being fixed. You need to identify the bad health states first, you can do that with this script, just don't run the ResetMonitoringState bit.

$a=gc c:\temp\file.txt
$Monitor="Certificate.Monitor.CheckExpiry"
$Class="Certificate.Class.WindowsCertificate"
$Severity="Error" # Must match health state of the monitor (Success, Error, Warning)
$MonitorToReset = Get-SCOMMonitor -Name $Monitor
$Monitoringclass = Get-SCOMClass -Name $Class
foreach($i in $a) {
($Monitoringclass | Get-SCOMClassInstance | where {$_.HealthState -eq $Severity -and $_.path -eq $i}).ResetMonitoringState($MonitorToReset) | select Status
}

Overrides

Get rules from mp that have the enable=true override

This is handy when setting up mps for the first time and you need to see if there’s any pre-configured overrides.

$a=Get-SCOMManagementPack -name Microsoft.Windows.Server.2008.Monitoring | get-scomrule # or get-scommonitor
foreach ($i in $a) {
if ($i.HasNonCategoryOverride -eq "true") {
$z=$i.displayname
$v=$i | get-scomoverride
if ($v.value -eq "true") {
write-host $v.property "-" $v.value "-" $z
}}}

Resource pools

Get resource pool and members

$a=Get-SCOMResourcePool | sort DisplayName
foreach ($i in $a) {
$b=get-scomresourcepool -displayname $i.displayname
write-host -foregroundcolor yellow $b.displayname
$b.members | % {write-host $_.DisplayName}
write-host
}

Rules

Get rules in an mp

The  HasNonCategoryOverride  property means (usually) that there's an override within the mp.

Get-SCOMManagementPack -name Microsoft.Windows.Server.2016.Monitoring | Get-SCOMRule | sort Enabled | ft name, Enabled, HasNonCategoryOverride

Tasks

Get tasks run by users

$Output=""
$a=Get-SCOMTaskResult | sort TimeStarted -desc
$a | % {
$Task=Get-SCOMTask -Id $_.TaskId
$SubmittedBy=$_.SubmittedBy
$TaskName=$Task.DisplayName
$TimeStarted=$_.TimeStarted.ToLocalTime()
$FormatTimeStarted=$TimeStarted.ToString("dd/MM/yyyy HH:mm:ss")
$Output+="$SubmittedBy - $TaskName - $FormatTimeStarted`n"
}
$Output

User roles

This gets SCOM user roles and members.

$c=Get-SCOMUserRoleforeach ($i in $c) {
$b=Get-SCOMUserRole -displayname $i.displayname
write-host -foregroundcolor yellow $i.displayname;$b.users
write-host
}

Select-String

Search a file for multiple strings

This will search a csv file for the strings Intelli or DynCache:

Select-String -Pattern Intelli,DynCache C:\temp\Services_Auto.csv | select line

Services

Set a service to automatic start type

Set-Service -Name SMS_SITE_COMPONENT_MANAGER -StartupType Automatic

Export to csv

get-service | sort DisplayName | select displayname, name, starttype, status | Export-Csv Windows_Services.csv

Filter for two different service names

Get-Service | where {$_.displayname -match 'commvault' -or $_.displayname -match 'intellisnap'} | sort displayname | select displayname, name, starttype, status

Filter for automatic start mode

Note: Examples that filter on automatic start type will not show if it's delayed or trigger start type. See this article for more.

get-service | sort DisplayName | select displayname, name, starttype, status | where {$_.starttype -eq 'automatic'}

Filter for automatic start mode and two different service names

Not 100% sure this works.

Get-Service | where {$_.starttype -eq 'automatic' -and ($_.displayname -match 'mcafee' -or $_.displayname -match 'trellix')} | sort displayname | select displayname, name, starttype, status

Filter for automatic start mode on multiple computers

This reads in a file of computer names, connects to them and gets all services with automatic start type then writes the output to a csv file. This is useful when building mps for service monitoring.

$count=0
$displayname=""
$file=""
$file+="FQDN^SVC_DISPLAYNAME^SVC_NAME^SVC_STARTTYPE`r"
$a=gc "C:\temp\file.txt" | sort
$output="C:\temp\Services_Auto.csv"
$total=$a.count
foreach ($i in $a) {
$count=$count+1
write-host -foregroundcolor yellow "$count/$total $i"
$b=Get-Service -ComputerName $i | where {$_.starttype -eq 'automatic'} | sort displayname | select displayname, name, starttype
foreach ($c in $b) {
$displayname=$c.displayname
$name=$c.name
$starttype=$c.starttype
write-host "$i^$displayname^$name^$starttype"
$file+="$i^$displayname^$name^$starttype`r"
}}
write-host -foregroundcolor yellow "Exporting output to $output"
$file | out-file $output

Add a service

You can't start the service so this is kind of lame for testing.

$params = @{
Name = "MCAFEETOMCATSRV5100"
BinaryPathName = "c:\windows\notepad.exe"
#DependsOn = "NetLogon"
DisplayName = "TEST Trellix ePolicy Orchestrator 5.10.0 Application Server"
StartupType = "Automatic"
Description = "This is a test service."
}
New-Service @params

Remove a service

Got a feeling you need latest version of PowerShell to do this:

Remove-Service -Name "TEST Trellix ePolicy Orchestrator 5.10.0 Application Server"

Start and Stop a service

Start-Service "Citrix Licensing"

Stop-Service "Citrix Licensing"

SharePoint

Compare SharePoint list to SQL table

I used this when I had to compare SharePoint list items that were mirrored (via a SCO runbook) to a SQL table. They often got out of sync and this helped me quickly work out what was missing.

Note: Invoke-Command can be slow.

If((Get-PSSnapin | Where {$_.Name -eq "Microsoft.SharePoint.PowerShell"}) -eq $null) {Add-PSSnapin Microsoft.SharePoint.PowerShell}
$HostName = $env:computername
$SPointUrl = "http://$HostName"
$SPointList = "SnowCiToRunbook"
$SQLInstance = "Server\Instance"
$SQL = @(Invoke-Sqlcmd -Query "Add your query here that returns 1 column only. Keep the double quotes" -ServerInstance $SQLInstance) | Select-Object -ExpandProperty SnowCatalogItem
$SPointWeb = Get-SPWeb $SPointUrl
$spSourceList = $SPointWeb.Lists[$SPointList]
$SPoint = $spSourceList.items | sort name | select name
ForEach ($a in $SPoint) {
$item = $a.name
$match = Select-String -InputObject $SQL "$item" -Quiet -SimpleMatch
If ($match -eq $true) {
#Write-Host -ForegroundColor green $item.ToUpper() ", Yes"
$countmatch = $countmatch + 1
} Else {
Write-Host -ForegroundColor red $item.ToUpper() ", No"
$countnomatch = $countnomatch + 1
}}
Write-Host
Write-Host -ForegroundColor yellow "SharePoint:" $SPoint.count
Write-Host -ForegroundColor yellow "SQL:" $SQL.count

Get number of columns in a SharePoint list

I used this when I had to compare the same lists from different SharePoint farms. It was a quick and dirty to get the job done but you can easily expand it get other info.

$Lists = "VDesktopApps", "VDesktopClientConfig", "vDesktopLanguages", "vDesktopLocations", "VDesktopOSOffice", "vDesktopPools", "VDesktopType"
If((Get-PSSnapin | Where {$_.Name -eq "Microsoft.SharePoint.PowerShell"}) -eq $null) {Add-PSSnapin Microsoft.SharePoint.PowerShell}
$HostName = $env:computername
$sourceWebURL = "http://$HostName/mws" #Run Get-SPSite to get Url list.
ForEach ($sourceListName in $Lists)
{
$spSourceWeb = Get-SPWeb $sourceWebURL
$spSourceList = $spSourceWeb.Lists[$sourceListName]
$fields = $spSourceList.Fields
Write-Host -ForegroundColor yellow "List:" $sourceListName, $fields.count
}

VMware

Setup

There's no order to this, you may need to run all of them or none of them.

Get-Module -Name vmware*

Import-Module -Name VMware.PowerCLI

Get-VICommand

I've had to use this on some servers, it's some weird cert issue, possible because it's not using ssl.

Get-PowerCLIConfiguration

Set-PowerCLIConfiguration -Scope User -InvalidCertificateAction warn

Connect or disconnect VCenter

Connect-VIServer VcenterServer -User username -password password

This shows which vcenter you're connected to. | gm has interesting stuff.

$global:DefaultVIServer

Disconnect-VIServer VcenterServer

Get VM info

If you're connecting to multiple vcenters and getting info, I think you need to disconnect from each one first, otherwise the vm count gets weird.

(get-vm).count

Get powered on VMs

poweredoff is...aah yep.

(Get-VM | where {$_.PowerState -eq "poweredon"}).count

A bit more funk

$Array=@(your_list)
write-host -foregroundcolor yellow "VCENTER - ON - OFF"
foreach($i in $Array) {
Connect-VIServer $i -User USER_NAME -password PASSWORD
$Total=(get-vm).count
$On=(Get-VM | where {$_.PowerState -eq "poweredon"}).count
$Off=(Get-VM | where {$_.PowerState -eq "poweredoff"}).count
write-host "$Total - $On - $Off"
Disconnect-VIServer -Server $i -Confirm: $false
}

Get-VMGuest

You need vmtools for this.

Options to get FQDN (not all VMs will have it so might be blank).

Criteria: Powered on, Server OS, return FQDN only:

(Get-VM | where {$_.PowerState -eq "poweredon" -and $_.guest -match "Microsoft Windows Server"}).ExtensionData.Guest.HostName

Some others:

(Get-VM -Name VM).ExtensionData.Guest.HostName

(Get-VM -Name VM | Get-VMGuest).ExtensionData.hostname

Testing this:

$file=""
$vcenter=VCENTER
$file+="NAME^FQDN^OS^POWER`r"
$output="C:\temp\" + $vcenter + "_VMs.csv"
#$a=Get-VM | sort name
$a=Get-VM | where {$_.PowerState -eq "poweredon" -and $_.name -match "ctrx"}
foreach($i in $a) {
$fqdn=$i.ExtensionData.Guest.HostName
$os=$i.Guest.OSFullName
$power=$i.PowerState
write-host "$i^$fqdn^$os^$power"
$file+="$i^$fqdn^$os^$power`r"
}
$file | out-file $output

XML

Query XML file

This shows the servers you have in an Remote Desktop Connection Manager .rdg file.

[xml]$a=Get-Content C:\temp\servers.rdg
$a.RDCMan.file.group.server.properties.name

Comments