Ouput PostgreSQL query into INT powershell variable - postgresql

I am quite new in using Powershell and try to output the result of a PostgreSQL query into a Powershell variable in order to use as a trigger for sending emails.
The returned value is a numeric value = 1 but it is considered as a system.Object and thus not recognised as INT.
See my code below (all email related code removed, no issue on that part)
# QUERY FOR EMAIL TRIGGER
Set-Location "C:\Program Files\pgAdmin 4\v4\runtime\";
$sql_trigger = $(.\psql -h $Server -p $DBPort -U $User -d $Database -w -v ON_ERROR_STOP=1 -c "select trigger_value from my_table ;" -t)
$trigger = $sql_trigger
Write-Host "trigger is "$trigger
[int]$_trig_false = 0
[int]$_trig_true = 1
IF ($trigger -as [int] -eq $_trig_false) {
Write-Host "Trigger value is 0 and will trigger an ERROR email"
}
ELSEIF ($trigger -as [int] -eq $_trig_true) {
write-host "Trigger value is 1 and will send email with file attached"
}
ELSE {
Write-Host "TRIGGER NOT READY"
#exit
}
here is the result.
trigger is 1
TRIGGER NOT READY
Many thanks in advance for the support

Related

Why is there a $ before the name of a variable in coding

What does the $ symbol mean? I saw it in this script:
function sendColor($colorName)
{
$portInfo = ( Get-WmiObject Win32_SerialPort | Where { $_.PNPDeviceID -like '*VID_239A*' } | select -last 1 )
$port = new-Object System.IO.Ports.SerialPort $portInfo.DeviceID,9600,None,8,one
$port.open()
$text = $colorName + "`r"
$port.Write($text)
start-sleep -m 50
$port.ReadExisting()
$port.Close()
}
if ($args.Length -eq 0)
{
echo "Usage: ColorChange <color>"
}
else
{
sendColor($args[0])
}
As far as I know this is a PowerShell script, but I'm not sure.
Taken from the documentation in:
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_variables?view=powershell-7
"A variable is a unit of memory in which values are stored. In PowerShell, variables are represented by text strings that begin with a dollar sign ($), such as $a, $process, or $my_var."

Windows NRPE - invalid return code: -196608 Nagios Core

I have this Powershell script for monitoring AD sync status:
Param(
[Parameter(Mandatory=$false,Position=0)]
[ValidateNotNullOrEmpty()]
[int]$Warning=1,
[Parameter(Mandatory=$false,Position=1)]
[ValidateNotNullOrEmpty()]
[int]$Critical=5
)
# Variables
$SyncErrors=0
$NagiosStatus = 0
$NagiosOutput = ""
$Syncs = 0
# Get AD Replication Status for this DC
$SyncResults = Get-WmiObject -Namespace root\MicrosoftActiveDirectory -Class MSAD_ReplNeighbor -ComputerName $env:COMPUTERNAME |
select SourceDsaCN, NamingContextDN, LastSyncResult, NumConsecutiveSyncFailures, #{N="LastSyncAttempt"; E={$_.ConvertToDateTime($_.TimeOfLastSyncAttempt)}}, #{N="LastSyncSuccess"; E={$_.ConvertToDateTime($_.TimeOfLastSyncSuccess)}}
# Process result
foreach ($SyncResult in $SyncResults)
{
if ($SyncResult.LastSyncResult -gt 0){
$NagiosOutput += "$($SyncResult.NumConsecutiveSyncFailures) failed sync with DC $($SyncResult.SourceDsaCN) on $($SyncResult.NamingContextDN) at $($SyncResult.LastSyncAttempt), last success sync at $($SyncResult.LastSyncSuccess)."
$SyncErrors++
if ($SyncErrors -eq $Warning){
$NagiosStatus = 1
}
elseif ($SyncErrors -eq $Critical) {
$NagiosStatus = 2
}
}
else{
$Syncs++
}
}
# Nagios Output
$NagiosOutput += " | Syncs=$($Syncs);;;; SyncErrors=$($SyncErrors);$Warning;$Critical;;"
if ($NagiosStatus -eq 2) {
Write-Host "CRITICAL: Replication error: $($NagiosOutput)"
$host.SetShouldExit(2)
}
elseif ($NagiosStatus -eq 1) {
Write-Host "WARNING: Replication error: $($NagiosOutput)"
$host.SetShouldExit(1)
exit 1
}
else{
Write-Host "OK: replication is up and running.$($NagiosOutput)"
$host.SetShouldExit(0)
exit 0
}
nslient.ini:
[/settings/external scripts/scripts]
check_ad_replication = cmd /c echo \scripts\check_ad_replication.ps1; exit($lastexitcode) | powershell.exe - Command -
Script is located in script folder,
./check_nrpe -H 1.2.3.5
I (0.5.2.35 2018-01-28) seem to be doing fine...
From Nagios server getting
./check_nrpe -H 1.2.3.5 -c check_ad_replication -t 30
The command (check_ad_replication) returned an invalid return code: -196608
Tried to set exit 1 - 3 for exit codes but no changes, from Powershell command runs just fine. Does anyone knows what should be set for error codes
Issue solved, had to add quotes around exit codes, example:
$NagiosStatus -eq "2"

Using a variable in a PowerShell script

I'm trying to put a small collection of simple scripts together for PowerShell to make life easier but am having some problems with variables in these scripts.
In a Linux environment I would use a variable in my scripts (usually $1, $2, etc....) like this to make things easier
sed -i 's/$1/$2/g' filename.conf
So that all I would need to do is this
./findreplace.sh old new filename.conf
In powershell, I want to achieve similar, specifically with this command:
Get-ADPrincipalGroupMembership account.name | select name
In this case, the $1 would be where 'user.name' is, so that I would be doing:
.\groups.ps1 user.name
Is there the facility for this?
Groups.ps1 should have the following content:
param( $user )
Get-ADPrincipalGroupMembership $user | Select Name
You can then invoke it as shown, or as .\Groups.ps1 -user user.name.
However, I'd probably try to do it as an "advanced command", and allow it to handle multiple names, and also names passed in via the pipeline:
[CmdletBinding()]
param (
[Parameter(ValueFromPipeline=$true;ValueFromPipelineByPropertyName=$true)]
[Alias("Identity","sAMAccountName")
string[] $Users
)
PROCESS {
ForEach ($User in $Users) {
Get-ADPrincipalGroupMembership $User | Select Name
}
}
which would also allow you to do something like Get-ADUser | .\Groups.ps1
You can add for loop form example script above:
for ($i = 0; $i -lt $args.Length; $i++) { Set-Variable -Scope Script -Name ($i + 1) -Value $args[$i] }
Write-Host "1: $1"
Write-Host "2: $2"
But more easy is just to declare script parameter as:
param($1, $2)
Write-Host "1: $1"
Write-Host "2: $2"
By the way it's bad practice to declare variables as numbers.

TFS2015 Powershell on Target Machine - Set a variable in the release process / Find a free port on a remote server

I want to get a free port from my deployment server. To achieve this I run this powershell-script and I want to set the passed in variable in my release process. Is there a good solution to set a variable in my release process which was calculated on a remote server (the deployment target in this case).
I also tried to use write-host to set the variable but than the script crashed in my release process..
Param(
[string]$variableName
)
$port = 1000
for($i=1000;$i -le 65000;$i++){
$free = netstat -o -n -a | findstr ":$i"
IF([string]::IsNullOrEmpty($free)) {
$port = $i
break;
}
}
Write-Output "##vso[task.setvariable variable=$variableName]$port"
Or is there a better way to find a free port on a remote deployment target?
For anyone needing a solution to set a build/release variable from a "PowerShell on Target Machine" task this worked for me:
Write-Verbose ("##vso[task.setvariable variable=SomeVariable]{0}" -f $theValue) -verbose
Based on my test, set variable isn’t working in PowerShell On Target Machine task.
You can store variable value in a file, then read data from that file.
here is the correct script. I just use the normal powershell task and run the following script, than I can set the variable correctly.
Param(
[string]$remoteServer,
[string]$variableName
)
Write-Host "Parameters: Server: " $remoteServer
$port = 80
$usedPorts = invoke-command -ComputerName $remoteServer -ScriptBlock { return Get-WebBinding }
Write-Host "Got Ports: $usedPorts"
for($i=8000;$i -le 65000;$i++){
$free = $usedPorts | findstr ":$i"
IF([string]::IsNullOrEmpty($free)) {
$port = $i
break;
}
}
Write-Host "Found port: " $port
Write-Host "##vso[task.setvariable variable=$variableName;]$($port)"
exit 0

Executing command doesn't result in script exception

We have a powershell script that deploys a database script. However, if the database script fails, the output doesn't throw exceptions to the powershell script.
Below is an example of the .ps1 file:
function Publish-DatabaseProject
{
sqlcmd -S . -b -v DatabaseName=Integration -q "alter table xx add test Varchar(10)"
}
function Add-Timestamp {
process {
if ($_.GetType() -eq [string]) {
"[$(Get-Date -Format o)] $_"
} else {
$_
}
}
}
function Write-LogFile {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)] [string] $Path,
[Parameter(Mandatory=$true, ValueFromPipeline=$true)] [object[]] $InputObject
)
begin {
$root = Split-Path -Path $Path -Parent
if ($root -and !(Test-Path -Path $root)) { New-Item -Path $root -Type Directory
| Out-Null }
}
process {
$InputObject |
Add-Timestamp |
Tee-Object -File $Path -Append
}
}
Publish-DatabaseProject -ErrorVariable DeployError 2>&1 |
Write-LogFile -Path "C:\output.log"
if ($DeployError -and $DeployError.Count -ne 0)
{
Write-Output "Failed"
} else
{
Write-Output "Succeeded"
}
The query in question is executing against a non-existent table. The text output shows:
[2015-12-11T14:42:45.1973944+00:00] Msg 4902, Level 16, State 1, Server ABDN-DEV-PC1, Line 1
[2015-12-11T14:42:45.2053944+00:00] Cannot find the object "xx" because it does not exist or you do not have permission
s.
Succeeded
I am expecting the last line to read: Failed.
If you run the sqlcmd line on its own, and follow it up with $LastExitCode, it does spit out a non-zero exit code.
> sqlcmd -S . -b -v DatabaseName=Integration -q "alter table xx add test Varchar(10)"
Msg 4902, Level 16, State 1, Server ABDN-DEV-PC1, Line 1
Cannot find the object "xx" because it does not exist or you do not have permissions.
> $LastExitCode
1
For various reasons, we cannot use Invoke-SqlCmd, and need to stick with SQLCMD.exe.
How can we make exceptions from within SQLCMD bubble out correctly to the calling script?
Your -ErrorVariable DeployError statement would only get triggered if the Publish-DatabaseProject cmdlet itself fails to execute. As that function is mostly a wrapper around sqlcmd.exe, there isn't any intelligence to bubble up this error. We can wrap it though by using the $LastExitCode automatic variable.
function Publish-DatabaseProject
{
sqlcmd -S . -b -v DatabaseName=Integration -q "alter table xx add test Varchar(10)"
if ($LastExitCode -ne 0)
{
Write-error $LastExitCode
throw $LastExitCode
}
}
Now, PowerShell will catch this error from the .exe, and you can use -ErrorVariable.
Update
So, since you want to keep running and not abandon ship when enountering an error, we need to wrap your Publish-DataBaseProject function with a try{}catch{} block, to catch the error we're generating, without stopping execution.
try {Publish-DatabaseProject -ErrorAction STOP -ErrorVariable DeployError 2>&1 |
Write-LogFile -Path "C:\output.log" }
catch{
Write-Output "Current job $($_), failed"
Write-Output "Exception $($Error.ExceptionID)"
}
Now we're properly generating an exception from a CMD, bubbling it up through our Function, and handling it as if it were a normal function, all using Native PowerShell. I believe this is what you were seeking to do. If not, post a gist of the whole script and I'll help you in a more targeted fashion.