How to convert awk match to powershell command? - powershell

I am currently running this command on a linux machine to get pods older than 1 day:
kubectl get pod | awk 'match($5,/[0-9]+d/) {print $1}'
I want to be able to run the same command in Powershell. How could I do it?
kubectl get pod output:
NAME READY STATUS RESTARTS AGE
pod-name 1/1 Running 0 2h3m
pod-name2 1/1 Running 0 1d2h
pod-name3 1/1 Running 0 4d4h
kubectl get pod | awk 'match($5,/[0-9]+d/) {print $1}' output:
pod-name2
pod-name3

You can use:
$long_running_pods=(kubectl get pod | Tail -n+2 | ConvertFrom-String -PropertyNames NAME, READY, STATUS, RESTARTS, AGE | Where-Object {$_.AGE -match "[1-9][0-9]*d[0-9]{1,2}h"})
$long_running_pods.NAME
This will give you all pods which have been running for more than one day.
Example:
$long_running_pods=(echo 'NAME READY STATUS RESTARTS AGE
pod-name 1/1 Running 0 1d2h
pod-name2 1/1 Running 0 0d0h' | Tail -n+2 | ConvertFrom-String -PropertyNames NAME, READY, STATUS, RESTARTS, AGE | Where-Object {$_.AGE -match "[1-9][0-9]*d[0-9]{1,2}h"})
$long_running_pods.NAME
will print:
pod-name

Awk might be a little more convenient in this case. You have to prevent the $split array from being spun out in the pipe before where-object. It turns out I can still reference the $split variable in the foreach-object.
' NAME READY STATUS RESTARTS AGE
pod-name 1/1 Running 0 2h3m
pod-name2 1/1 Running 0 1d2h
pod-name3 1/1 Running 0 4d4h' | set-content file
get-content file |
where-object { $split = -split $_; $split[4] -match '[0-9]+d' } |
foreach-object { $split[0] }
pod-name2
pod-name3

Related

Using sql query in shell script

I have a shell script that uses output from a sql query and based on the value of one column sends out an alert. However i don't think it's capturing the value. although the value is not greater than 0 yet it still sends out an email.
Any idea where i am going wrong? Thanks.
............................................................................
#!/bin/sh
psql -d postgres -U postgres -c "select pid,application_name,pg_wal_lsn_diff(pg_current_wal_lsn(), sent_lsn) sending_lag,pg_wal_lsn_diff(sent_lsn,flush_lsn) receiving_lag,pg_wal_lsn_diff(flush_lsn, replay_lsn) replaying_lag,pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) total_lag from pg_stat_replication;"| while read total_lag;
do
echo $total_lag
lag1=$(echo $total_lag)
done
if [[ $lag1 -ge 0 ]]
then echo "Current replication lag is $lag1" |mail -s "WARNING!" abcd#mail.com
else
echo "No issue"
fi
............................................................................
this is the output of above query
pid | application_name | sending_lag | receiving_lag | replaying_lag | total_lag
-------+------------------+-------------+---------------+---------------+-----------
27823 | db123 | 0 | 0 | 0 | 0
27824 | db023 | 0 | 0 | 0 | 0

Sort output from `docker ps` in powershell while keeping table header at the top

In my powershell profile I have a shortcut to docker ps, with the format set to improve readability
function dps {
docker ps --format "table {{.Names}}\t{{.ID}}\t{{.Status}}\t{{.Ports}}" | Sort-Object
# ????
# Tee-Object -Variable lines |
# select -first 1 |
# Write-Host;
# $lines | Sort-Object | Write-Host # Prints nothing
}
Sorting the lines in this way works nicely and groups my containers by name, but the table header ends up in the middle of the output.
You can see that I tried to separate out the first line of output (the header), but I couldn't figure out how to get the table to continue to print. How can I keep the table header at the top while sorting and printing the table?
Sample Output
database_A 27b33272e64c Up 15 hours 3306/tcp, 33060/tcp
database_B 1b1662223f17 Up 15 hours 33060/tcp, 0.0.0.0:33640->3306/tcp
database_C 8f98fc0890cc Up 15 hours 3306/tcp, 33060/tcp
framework_A a0d829729c8e Up 15 hours (unhealthy) 5050/tcp, 0.0.0.0:5170->80/tcp
NAMES CONTAINER ID STATUS PORTS
service_A 8708aec85ea7 Up 15 hours (healthy) 0.0.0.0:5100->8080/tcp
service_B 7931365f450e Up 15 hours (unhealthy) 5160/tcp, 0.0.0.0:5160->80/tcp
service_C e9b9272011d8 Up 15 hours (unhealthy) 5160/tcp, 0.0.0.0:5110->80/tcp
I suggest to convert tab delimited output to an object first, then sort.
function dps {
docker ps --format "table {{.Names}}\t{{.ID}}\t{{.Status}}\t{{.Ports}}" |
ConvertFrom-Csv -delimiter "`t" |Sort-Object Names
}
Should return this:
NAMES CONTAINER ID STATUS PORTS
----- ------------ ------ -----
database_A 27b33272e64c Up 15 hours 3306/tcp, 33060/tcp
database_B 1b1662223f17 Up 15 hours 33060/tcp, 0.0.0.0:33640->3306/tcp
database_C 8f98fc0890cc Up 15 hours 3306/tcp, 33060/tcp
framework_A a0d829729c8e Up 15 hours (unhealthy) 5050/tcp, 0.0.0.0:5170->80/tcp
service_A 8708aec85ea7 Up 15 hours (healthy) 0.0.0.0:5100->8080/tcp
service_B 7931365f450e Up 15 hours (unhealthy) 5160/tcp, 0.0.0.0:5160->80/tcp
service_C e9b9272011d8 Up 15 hours (unhealthy) 5160/tcp, 0.0.0.0:5110->80/tcp
Try using same output without headers:
docker ps --format "{{.Names}}\t{{.ID}}\t{{.Status}}\t{{.Ports}}" | Sort-Object
LotPing's answer was close but duplicated the header information. Combining it with Volodymyr's answer gives us this:
function dps {
docker ps --format "{{.Names}}\t{{.ID}}\t{{.Status}}\t{{.Ports}}" |
ConvertFrom-CSV -Delimiter "`t" -Header ("Names","Id","Status","Ports") |
Sort-Object Names
}
This has the desired output! Thanks everyone.

PowerShell display duplicates in CSV

I have a csv with headers like this
ID,Name,IP,Details
There are some value will be duplicated like this
1,John,192.168.1.1,Details1
2,Mary,192.168.1.2,Details2
3,John,192.168.1.3,Details3
4,Dick,192.168.1.1,Details4
5,Kent,192.168.1.4,Details5
Is there anyway I can select all lines with duplicated values?
Desired Output:
1,John,192.168.1.1,Details1
3,John,192.168.1.3,Details3
4,Dick,192.168.1.1,Details4
So far I have tried
Import-csv file | group | sort -des | select -f 10
but the result only group those with whole lines matching
I will be appreciate if anyone could lend a hand or show direction for me to solve this question. Thanks in advance for any reply
I'm not sure if I've understood your problem up to 100%, but as far as I've understood you want something like this:
# ID Name IP Detail
#-- ---- -- ------
#1 John 192.168.1.1 Details1
#2 Mary 192.168.1.2 Details2
#3 John 192.168.1.3 Details3
#4 Dick 192.168.1.1 Details4
#5 Kent 192.168.1.4 Details5
$input = Import-csv .\input.csv
$input
$uniqueNames = $input.Name | select -Unique
$duplicateNames = Compare-Object -ReferenceObject $input.Name -DifferenceObject $uniqueNames | ? { $_.SideIndicator -like "<=" } | select -ExpandProperty InputObject
$uniqueIps = $input.IP | select -Unique
$duplicateIps = Compare-Object -ReferenceObject $input.IP -DifferenceObject $uniqueIps | ? { $_.SideIndicator -like "<=" } | select -ExpandProperty InputObject
Write-Output ""
Write-Output "========================="
Write-Output "Duplicate Names: $duplicateNames"
Write-Output "Duplicate IPs: $duplicateIps"
Output:
ID Name IP Detail
-- ---- -- ------
1 John 192.168.1.1 Details1
2 Mary 192.168.1.2 Details2
3 John 192.168.1.3 Details3
4 Dick 192.168.1.1 Details4
5 Kent 192.168.1.4 Details5
=========================
Duplicate Names: John
Duplicate Names: 192.168.1.1
Hope that helps.

How can I count running EC2 Instances?

I'm looking for a very basic script to count the number of running EC2 instances at AWS using PowerShell. I have found several methods but for some reason when I try them, I do not get the results I expect.
The closest I have is this:
$instancestate = (get-ec2instance).instances.state.name
$instancestate
which returns:
stopped
running
stopped
stopped
running
(the list goes on for about 80 instances)
I wish to have a response that counts those which are running.
I'm not sure about others, but I prefer to explicitly assign my ec2 filters to variables, and then list them when calling something like Get-EC2Instance. This makes it easier to work with filters if you need to to filter on multiple conditions.
Here's a working example of what you're after, where I have 6 running instances:
# Create the filter
PS C:\> $filterRunning = New-Object Amazon.EC2.Model.Filter -Property #{Name = "instance-state-name"; Value = "running"}
# Force output of Get-EC2Instance into a collection.
PS C:\> $runningInstances = #(Get-EC2Instance -Filter $filterRunning)
# Count the running instances (more literally, count the collection iterates)
PS C:\> $runningInstances.Count
6
Count all instances with separate counters for total, running and stopped ones:
(Get-EC2Instance).Instances | group InstanceType | select Name,
#{n='Total';e={$_.Count }}, #{n='Running';e={($_.Group | ? { $_.state.Name -
eq "running" }).Count }}, #{n='Stopped';e={($_.Group | ? { $_.state.Name -eq
"stopped" }).Count }}

Unexpected behavior with Get-Job when only one job running

I'm new to Powershell and I'm having an issue with the Get-Job command. In my script, I'm testing out multi-threading and am doing something like:
$Program = {
"Thread " + $args[0];
Start-Sleep 5;
}
Start-Job $Program -ArgumentList #($i) | Out-Null
The Start-Job call is actually in a loop in which I'm creating multiple jobs. Below this, I have:
Get-Job
"Jobs Running: " + $(Get-Job -State Running).count
If there are multiple jobs running, I will get output like:
Id Name State HasMoreData Location Command
-- ---- ----- ----------- -------- -------
2201 Job2201 Running True localhost ...
2199 Job2199 Running True localhost ...
2197 Job2197 Running True localhost ...
2195 Job2195 Running True localhost ...
2193 Job2193 Completed True localhost ...
2191 Job2191 Completed True localhost ...
2189 Job2189 Completed True localhost ...
2187 Job2187 Completed True localhost ...
Jobs Running: 4
But if there is only one job running, it seems that $(Get-Job -State Running).count isn't returning anything:
Id Name State HasMoreData Location Command
-- ---- ----- ----------- -------- -------
2207 Job2207 Running True localhost ...
Jobs Running:
As you can see, there is one job running, but $(Get-Job -State Running).count doesn't return anything. Any idea what's happening here? To me, it looks like that if there are multiple jobs, $(Get-Job -State Running) returns a collection of jobs which has the .count property, whereas if there is only one job, it returns just that job, and doesn't have the .count property. If this is the case (or if I'm doing something wrong), what command should I be using to get my expected result of $(Get-Job -State Running).count == 1?
Try using Measure-Object
$(Get-Job -State Running | Measure-Object).count
In PS 2.0 count only works on arrays. When Get-Job only returns one job, it returns it as an OBJECT, not an array. To make it work, you could e.g. force Get-Job to always return an array by using #(code) . Try this:
$Program = {
"Thread " + $args[0];
Start-Sleep 5;
}
Start-Job $Program -ArgumentList #($i) | Out-Null
Get-Job
"Jobs Running: " + $(#(Get-Job -State Running).count)