print strings and variables in powershell for loop - powershell

I need to extract an alerts from rest api and sent it to a file with powershell
I was able to extract the alerts outputs looping the xml file:
foreach ($c in $temp){$c.timeOfAlertFormatted,$c.parent,$c.child,$c.category,$c.servicePlanDisplayName,$c.message}
Thu 09/19/2019 12:00:19 AM
IL
Servername
Phase Failure
Gold
One or more source luns do not have a remote target specified/mapped.
Wed 09/18/2019 02:18:25 PM
IL
Server2
Phase Failure
Gold
One or more source luns do not have a remote target specified/mapped
I am new to PS , what i want to achieve is to add descriptive string
to each filed, i.e:
Time: Thu 09/19/2019 12:00:19 AM
Country: IL
Server: servername
etc ,the rest of the fields.
i tried :
foreach ($c in $temp){Write-Host "Time : $($c.timeOfAlertFormatted)"}
Time :
Time :
Time :
Time :
Time :
Time :
Time :
Time :
Time :
Time :
Time :
Time :
Time : Thu 09/19/2019 12:00:19 AM
its printing empty "Time" fields
here is example of the xml:

It looks like you have already loaded the xml and filtered out the properties you need in a variable $temp.
I think what you want can be achieved by doing:
$temp | Select-Object #{Name = 'Time'; Expression = {$_.timeOfAlertFormatted}},
#{Name = 'Country'; Expression = {$_.parent}},
#{Name = 'ServerName'; Expression = {$_.child}},
Category,ServicePlanDisplayName, Message
The above should output something like
Time : Thu 09/19/2019 12:00:19 AM
Country : IL
ServerName : Servername
Category : Phase Failure
ServicePlanDisplayName : Gold
Message : One or more source luns do not have a remote target specified/mapped.
Time : Wed 09/18/2019 02:18:25 PM
Country : IL
ServerName : Server2
Category : General Failure
ServicePlanDisplayName : Gold
Message : One or more source luns do not have a remote target specified/mapped.
If your variable $temp is NOT what I suspect it to be, please edit your question and show us the XML aswell as the code you use to extract the alerts from it.

Related

How can I filter .content from a invoke-webrequest command

I have an internal web app that provides connection statistics. I am trying to use PS to collect those statistics, which are in .conent. The .content property has a lot of other values I am trying to filter out and I haven't been very successful.
My Command:
invoke-webrequest -URI http://<my internal web site> | Select-Object -ExpandProperty Content
Returned Results:
Greetings from live node: server-name [ FQDN ] , serving at port: 443 since [4 days, 0 hour, 3
3 minutes, 33 seconds] with following settings:
IN_MEMORY_MESSAGE_LIFE_IN_HOURS : 1
DELIVERY_GRACE_WINDOW_IN_SECONDS : 10
BUILD_NUMBER : 4
STATISTICS_LOG_FREQUENCY_IN_MINUTES : 0
HEARTBEAT_INTERVAL_IN_MINUTES : 2
CLUSTERING_MODE : IMPLICIT
CLEAN_ORPHANED_SESSIONS : Y
OFFLOAD_SSL : Y
SERVICE_HOST : 192.168.1.1
REQUEST_TIMEOUT_MILLIS : 3000
SERVICE_PORT : 443
VALIDATE_REQUEST_CONTENT_TYPE : N
APP_BROADCAST_LIFE_IN_MINUTES : 1
DEFAULT_MESSAGE_LIFE_IN_DAYS : 1
VERSION : release/2008
ENABLE_IDLER_STATISTICS : Y
ORIGIN_STATS_EXPIRY_IN_MINUTES : 60
INCLUDE_CACHE_CONTROL_HEADER_IN_HEALTH_CHECK : N
DATABASE_PROVIDER : INMEMORY
QUEUEMONITOR_THREADPOOLSIZE : 100
BUILD_DATE : Mon 27 Jul 2020 10:02:44 AM EDT -0400
BUILD_PLAN : AWCM-AWCM302-JOB1-4
Persistence Store Type:INMEMORY , status: live
Current Active Sessions: 6
They only line I care about is "Current Active Sessions: 6" and really all I care about is the numerical value which I will use in a test later in the script.
How can I just grab the one value I need?
$iwr=invoke-webrequest -URI http://<my internal web site> |
Select-Object -ExpandProperty Content
$cas=$iwr -split [System.Environment]::NewLine |
Select-String -Pattern "Current Active Sessions:\s*(.*)"
$cas.Matches[0].Groups[1].Value
Above code snippet should return 6. Tested using the following (constant) value of $iwr instead of invoke-webrequest:
$iwr=#'
Greetings from live node: server-name [ FQDN ] , serving at port: 443 since [4 days, 0 hour, 3
3 minutes, 33 seconds] with following settings:
IN_MEMORY_MESSAGE_LIFE_IN_HOURS : 1
DELIVERY_GRACE_WINDOW_IN_SECONDS : 10
BUILD_NUMBER : 4
STATISTICS_LOG_FREQUENCY_IN_MINUTES : 0
HEARTBEAT_INTERVAL_IN_MINUTES : 2
CLUSTERING_MODE : IMPLICIT
CLEAN_ORPHANED_SESSIONS : Y
OFFLOAD_SSL : Y
SERVICE_HOST : 192.168.1.1
REQUEST_TIMEOUT_MILLIS : 3000
SERVICE_PORT : 443
VALIDATE_REQUEST_CONTENT_TYPE : N
APP_BROADCAST_LIFE_IN_MINUTES : 1
DEFAULT_MESSAGE_LIFE_IN_DAYS : 1
VERSION : release/2008
ENABLE_IDLER_STATISTICS : Y
ORIGIN_STATS_EXPIRY_IN_MINUTES : 60
INCLUDE_CACHE_CONTROL_HEADER_IN_HEALTH_CHECK : N
DATABASE_PROVIDER : INMEMORY
QUEUEMONITOR_THREADPOOLSIZE : 100
BUILD_DATE : Mon 27 Jul 2020 10:02:44 AM EDT -0400
BUILD_PLAN : AWCM-AWCM302-JOB1-4
Persistence Store Type:INMEMORY , status: live
Current Active Sessions: 6
'#
Try this:
$iwr=invoke-webrequest -URI http://<my internal web site> | Select-Object -ExpandProperty Content
$iwr|Select-String -Pattern "Current Active Sessions: (.*)"

Read in a *HUGE* CSV file, export specific columns based on column name in header, output comma delimited data

So, I know I can read in a csv file using import-csv like so:
$test = import-csv BPUSAUV20FARS-1000.csv
I found another stack overflow question which gave me some code to decipher column names, like so:
$columns = $test[0].psobject.properties.name
I found a reddit post that helped me find a way to extract multiple columns using select-object like so:
$properties = #('Index', 'Year', 'Day', 'Time', 'Line', 'Beam', 'Pos TPU', 'Depth TPU', 'Status')
$test |Select-Object $properties
But the output from the above command likes like this:
Index : 1
Year : EM2040-0073-1000-20200224-222235
Day : 25
Time : Accept
Line : 0.648
Beam : 24-FEB-2020:22:22:34.98
Pos TPU : 4.617
Depth TPU : 1124834.70
Status : 10247261.01
Index : 2
Year : EM2040-0073-1000-20200224-222235
Day : 26
Time : Accept
Line : 0.749
Beam : 24-FEB-2020:22:22:34.98
Pos TPU : 4.617
Depth TPU : 1124834.73
Status : 10247261.76
Index : 3
Year : EM2040-0073-1000-20200224-222235
Day : 27
Time : Accept
Line : 0.624
Beam : 24-FEB-2020:22:22:34.98
Pos TPU : 4.617
Depth TPU : 1124834.76
Status : 10247263.05
And what I need is this:
1,EM2040-0073-1000-20200224-222235,25,Accept,0.648,24-FEB-2020:22:22:34.98,4.617,1124834.70,10247261.01
I also need to be able to perform these actions on a few hundred files with several million lines each. The smallest file is about 2.4 million lines.
As for...
I also need to be able to perform these actions on a few hundred files
with several million lines each. The smallest file is about 2.4
million lines.
... dealing with large files in general --- (too long for just a comment)
As per MSDN
[IO.File]::OpenText and as noted in another Q&A
The Get-Content cmdlet does not perform as well as a StreamReader when
dealing with very large files. You can read a file line by line using
a StreamReader like this:
$path = 'C:\A-Very-Large-File.txt'
$r = [IO.File]::OpenText($path)
while ($r.Peek() -ge 0) {
$line = $r.ReadLine()
# Process $line here...
}
$r.Dispose()
Some performance comparisons:
Measure-Command {Get-Content .\512MB.txt > $null}
Total Seconds: 49.4742533
Measure-Command {
$r = [IO.File]::OpenText('512MB.txt')
while ($r.Peek() -ge 0) {
$r.ReadLine() > $null
}
$r.Dispose()
}
Total Seconds: 27.666803

From the SCCM client system, can you list the deployment(s) currently associated to a missing patches?

I'm attempting to build a PowerShell module to help diagnose SCCM issues without giving the system admins access to the SCCM console. The code below currently finds all missing patches on a system but i want to be able to organize them:
Organize patches by deployment name
Display the deployment install deadline
List the Patches missing
Code that gets all missing patches:
$Results = (get-wmiobject -ComputerName $env:ComputerName -query "SELECT * FROM CCM_UpdateStatus" -namespace "root\ccm\SoftwareUpdates\UpdatesStore" | Where-Object {$_.Status -eq "Missing"})
Output Snippet:
__GENUS : 2
__CLASS : CCM_UpdateStatus
__SUPERCLASS :
__DYNASTY : CCM_UpdateStatus
__RELPATH : CCM_UpdateStatus.UniqueId="4ffd2339-7fa5-4716-b64e-78e3dce16d59"
__PROPERTY_COUNT : 15
__DERIVATION : {}
__SERVER : ………………………………
__NAMESPACE : ROOT\ccm\SoftwareUpdates\UpdatesStore
__PATH : \\………………………………\ROOT\ccm\SoftwareUpdates\UpdatesStore:CCM_UpdateStatus.UniqueId="4ffd2339-7fa5-4716-b64e-78e3dce16d59"
Article : 3178662
Bulletin :
ExcludeForStateReporting : False
Language :
ProductID : e6cf1350-c01b-414d-a61f-263d14d133b4
RevisionNumber : 200
ScanTime : 20180320184935.000000+000
Sources : {{7D052A75-2032-4F02-BAC9-9EDA4DBD58DE}}
SourceType : 2
SourceUniqueId : {7D052A75-2032-4F02-BAC9-9EDA4DBD58DE}
SourceVersion : 68
Status : Missing
Title : Update for Microsoft Office 2016 (KB3178662) 32-Bit Edition
UniqueId : 4ffd2339-7fa5-4716-b64e-78e3dce16d59
UpdateClassification : e6cf1350-c01b-414d-a61f-263d14d133b4
PSComputerName : WGC1107B87PH2
I cannot determine how to get a patches associated deployment name or that patches install deployment deadline. Once I can get those two associations I would like to have output something like below:
Baseline Patch Deployment:
Install Deadline: Apr 12, 2018
Missing Patches:
Patch1
Patch2
Patch3
Office 2016 April Patch Deployment:
Install Deadline: Apr 27, 2018
Missing Patches:
Patch1
Patch2
Patch3
Missing but Unapproved Patches:
Install Deadline: None
Missing Patches
Patch1
Patch2
Patch3

Handling hash tables in custom objects

Our monitoring system has a REST API that I am trying to retrieve properties from, then output them to a custom object. A couple of the property values are hash tables.
In addition to keeping the custom objects for use in Powershell, I would like to export them to CSV, so I need those hash tables to be something else, so I don't end up with Syste.Object[] in those columns.
The object returned from the API looks like this (truncated):
$allServices[0]
alertStatus : none
ignoreSSL : True
description : Test service
stopMonitoring : False
stopMonitoringByFolder : False
useDefaultLocationSetting : False
serviceProperties : {}
transition : 1
alertStatusPriority : 100000
serviceFolderId : 1
script :
disableAlerting : False
individualAlertLevel : warn
checkpoints : {#{id=1; geoInfo=Overall; smgId=0}, #{id=2; geoInfo=US - Los Angeles; smgId=1}, #{id=3; geoInfo=US - Washington DC; smgId=2}, #{id=4; geoInfo=US - San Francisco; smgId=3}...}
pageLoadAlertTimeInMS : 30000
sdtStatus : none-none-none
serviceStatus : alive
method : tabledriven
id : 1
Then checkpoints looks like this:
$allServices[0].checkpoints
id geoInfo smgId
-- ------- -----
1 Overall 0
2 US - Los Angeles 1
3 US - Washington DC 2
4 US - San Francisco 3
5 Europe - Dublin 4
6 Asia - Singapore 5
What is the best way to deal with the checkpoints property?
Thanks.
Convert checkpoints (and possibly serviceProperties) to a JSON string.
$allServicesCSV = foreach ($srv in $allServices) {
$srv = $srv.PSObject.Copy() # shallow copy
$srv.checkpoints = ConvertTo-Json $srv.checkpoints -Compress
$srv
}
Well, the requirements changed, so I only need to output to json/XML and not to CSV, making this much easier. Thanks.

How to get a child item into a variable on its own

I am relatively sure this is quite easy to do but my google fu is not running strong
At the moment I am doing:
add-pssnapin windows.serverbackup
get-wbsummary
This returns me:
NextBackupTime : 07/09/2012 12:00:00
NumberOfVersions : 210
LastSuccessfulBackupTime : 06/09/2012 21:00:13
LastSuccessfulBackupTargetPath : \\?\Volume{bf315689-e5ed-11e1-a376-d067e5f384ea}
LastSuccessfulBackupTargetLabel : SBSERVE 2012_08_21 12:20 DISK_01
LastBackupTime : 06/09/2012 21:00:13
LastBackupTarget : SBSERVE 2012_08_21 12:20 DISK_01
DetailedMessage :
LastBackupResultHR : 0
LastBackupResultDetailedHR : 0
CurrentOperationStatus : NoOperationInProgress
What I want to do is get just the result portion (not its title into a variable) so for example $lastbackuptime = 07/09/2012 12:00:00
PS> $wbs = Get-WBSummary
PS> $lastbackuptime = $wbs.NextBackupTime