How to add hardcoded value to WMI output in Powershell - sql

I am new to powershell, i am trying to retrieve the SQL Services details using WMI object. My code is as follows:
$InputFile = Import-Csv "C:\input\Servers.csv" | %{ $_.Instance = $_.Instance -replace "\\.*?$" ; $_}
Write-Output "SQL Services details for Server:" | Out-File C:\output\SQLCHECK.STOPPED.LOG
Write-Output "********************************" | Out-File C:\output\SQLCHECK.STOPPED.LOG -Append
foreach($Servers in $Inputfile)
{
Write-Output $Servers|ft -AutoSize | Out-File C:\output\SQLCHECK.STOPPED.LOG
$Servicesstate=Get-WmiObject win32_service -ComputerName $Servers.instance | Select Name, Startmode, State | Where-Object `
{$_.name -like "*SQL*" -and $_.Startmode -match "Auto" -and $_.state -match "Stopped"} | ft -auto
if (!$Servicesstate )
{
Write-Host "No Services in STOP state"
Write-Output "No Services in STOPPED state" | Out-File C:\output\SQLCHECK.STOPPED.LOG -Append
}
Else
{
echo ($Servicesstate )
Write-Output ($Servicesstate) | Out-File C:\output\SQLCHECK.STOPPED.LOG -Append
}
}
My Output will come something like this:
Instance Name:
ABCDEFGH
Name Startmode State
SQLdmCollectionService$Default Auto Stopped
SQLdmManagementService$Default Auto Stopped
SQLdmPredictiveAnalyticsService$Default Auto Stopped
My question is, how to add a additional column to the output and add custom text as values.
I want to add remarks column and display failed if any services are stopped.
Name Startmode State Remarks
SQLdmCollectionService$Default Auto Stopped Failed
SQLdmManagementService$Default Auto Stopped Failed
SQLdmPredictiveAnalyticsService$Default Auto Stopped Failed

Your columns are defined by what you put in Select-Object, as you only have Name, Startmode and State those will be the columns.
Change
Select Name,Startmode,State
To
Select-Object Name,Startmode,State,Remark
By adding another property called Remarks you will effectively add another column to your output and you can change the value of Remark by calling the property like so
$Servicestate.Remark = 'Failed'
So you're final code might look something like this
$InputFile = Import-Csv "C:\input\Servers.csv" | %{ $_.Instance = $_.Instance -replace "\\.*?$" ; $_}
Write-Output "SQL Services details for Server:" | Out-File C:\output\SQLCHECK.STOPPED.LOG
Write-Output "********************************" | Out-File C:\output\SQLCHECK.STOPPED.LOG -Append
foreach($Servers in $Inputfile)
{
Write-Output $Servers|ft -AutoSize | Out-File C:\output\SQLCHECK.STOPPED.LOG
$Servicesstate=Get-WmiObject win32_service -ComputerName $Servers.instance | Select Name, Startmode, State | Where-Object `
{$_.name -like "*SQL*" -and $_.Startmode -match "Auto" -and $_.state -match "Stopped"} | ft -auto
if (!$Servicesstate )
{
# Edit the new column before you output
$Servicestate.Remark = 'Failed'
Write-Host "No Services in STOP state"
Write-Output "No Services in STOPPED state" | Out-File C:\output\SQLCHECK.STOPPED.LOG -Append
}
Else
{
# Edit the new column before you output
$Servicestate.Remark = 'Success'
echo ($Servicesstate )
Write-Output ($Servicesstate) | Out-File C:\output\SQLCHECK.STOPPED.LOG -Append
}
}

When assigning your values to $servicestate you can pipe to a Select command and create an extra value with a hashtable. Check out this slightly modified version of your script, paying close attention to line 9:
$InputFile = Import-Csv "C:\input\Servers.csv" | %{ $_.Instance = $_.Instance -replace "\\.*?$" ; $_}
Write-Output "SQL Services details for Server:" | Out-File C:\output\SQLCHECK.STOPPED.LOG
Write-Output "********************************" | Out-File C:\output\SQLCHECK.STOPPED.LOG -Append
foreach($Servers in $Inputfile)
{
Write-Output $Servers|ft -AutoSize | Out-File C:\output\SQLCHECK.STOPPED.LOG
$Servicesstate=Get-WmiObject win32_service -ComputerName $Servers.instance | Select Name, Startmode, State |
Where{$_.name -like "*SQL*" -and $_.Startmode -match "Auto" -and $_.state -match "Stopped"}|Select Name,Startmode,State,#{l='Remarks';e={if($_.State -eq "Stopped"){"Failed"}}}
if (!$Servicesstate )
{
Write-Host "No Services in STOP state"
Write-Output "No Services in STOPPED state" | Out-File C:\output\SQLCHECK.STOPPED.LOG -Append
}
Else
{
echo ($Servicesstate|ft -AutoSize )
Write-Output ($Servicesstate) |FT -auto| Out-File C:\output\SQLCHECK.STOPPED.LOG -Append
}
}

Related

How can i capture exceptions values using powershell

Hi i'm new to this and want to capture exception and store values in SQL database but its not capturing.
My current flow is something like this:
My code:
try
{
try
{
$path='D:\'+$name # location not present in my system to throw exception
"$(get-date -format "yyyy-MM-dd HH:mm:ss"):Folder Name : $($name)" | out-file $LogFile -Append
if (Test-Path -Path $path)
{
$status='already exists'
"$(get-date -format "yyyy-MM-dd HH:mm:ss"):Folder Already Exists" | out-file $LogFile -Append
write-output $status
$msg='Already Existed'
}
#else
#{
#Creating a folder
#New-Item -Path $path -ItemType Directory
#"$(get-date -format "yyyy-MM-dd HH:mm:ss"):Folder Created" | out-file $LogFile -Append
#$status='Success'
#$msg='Successfully Created'
#}
}
catch
{
#to catch above exceptions
$status='Failed'
Write-Host "`nError Message: " $_.Exception.Message
Write-Host "`nError in Line: " $_.InvocationInfo.Line
Write-Host "`nError in Line Number: "$_.InvocationInfo.ScriptLineNumber
Write-Host "`nError Item Name: "$_.Exception.ItemName
"$(get-date -format "yyyy-MM-dd HH:mm:ss"):$($_.Exception.Message)" | out-file $LogFile -Append
$msg=$_.Exception.Message
}
$CheckQuery="SELECT COUNT(1) AS TABLECOUNT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = '$($name)'"
$InsertQuery="INSERT INTO [$($Database)].[dbo].[$($name)]
([DATE],[HOST_NAME],[STATUS],[MESSAGE])
VALUES('$date','$ComputerName','$status','$msg')
"
$CreateQuery='CREATE TABLE '+$($name)+' (DATE NVARCHAR(MAX),HOST_NAME NVARCHAR(MAX),STATUS NVARCHAR(MAX),MESSAGE NVARCHAR(MAX))'
#other sql part making connection and calling queries
}
catch
{
#catching SQL part exceptions
Write-Host "`nError Message: " $_.Exception.Message
Write-Host "`nError in Line: " $_.InvocationInfo.Line
Write-Host "`nError in Line Number: "$_.InvocationInfo.ScriptLineNumber
Write-Host "`nError Item Name: "$_.Exception.ItemName
"$(get-date -format "yyyy-MM-dd HH:mm:ss"):$($_.Exception.Message)" | out-file $LogFile -Append
}
Exception I'm getting in powershell is
But in SQL it stores blank data as shown in below image
As I'm new to this ,any help will be thankfull.

powershell not exporting

hi i am running the following query in powershell:
Import-Module Hall.psm1
$Database = 'Report'
$Server = '192.168.1.2'
$Query = 'SELECT all * FROM [Report].[dbo].[TestView]'
$LogLocation = "\\Report\LogFile.csv"
$DynamicYear = (Get-Date).Year
$DynamicMonth = (Get-Culture).DateTimeFormat.GetMonthName((Get-Date).Month)
$FileDestination = "\\Report\MONTHLY REPORTS\"+$DynamicYear+"\"+$DynamicMonth+"\"
$Outputfilename='TestView-'+(Get-Date).ToString('MM-dd-yyyy')+'.csv'
$LocalCreate = 'C:\Scripts\LocalCreate\'
$FolderPathExtension = "Microsoft.PowerShell.Core\FileSystem::"
$CodeDestination = $FolderPathExtension+$FileDestination
$filedest=$LocalCreate+$outputfilename
$Logfile = $FolderPathExtension+$LogLocation
Invoke-sqlcmd -querytimeout 120 -query "
$Query
" -database $database -serverinstance $server |
ConvertTo-Csv -NoTypeInformation | # Convert to CSV string data without the type metadata
Select-Object -Skip 0 | # Trim header row, leaving only data columns
% {$_ -replace '"',''} | # Remove all quote marks
Set-Content -Path $filedest
(gc $filedest) | ? {$_.trim() -ne "" } | set-content $filedest
if(Test-Path ($filedest)) {
Move-Item -Path $filedest -Destination $CodeDestination -Force
$LogType = 'INFO'
$LogEntry = "$filedest MovedTo $To"
Write-Log -Message $LogEntry -Level $LogType -Logfile $Logfile
}
which works fine without any issue if the query has data.
however, if the query does not have any data it does not create a .csv. how can i get it to create a blank .csv? or .csv with headers only?
Use New-Item -ItemType File -Path $filedest before your Invoke-SqlCmd Or ConvertTo-Csv

Get variable from tenant in Octopus

Is there any way to get a variable from tenant in Octopus server?
I already extracting variable from projects, using code below, but this method is not working for tenants:
Import-Module "C:\Program Files\WindowsPowerShell\Modules\Octopus-Cmdlets\0.4.4\Octopus-Cmdlets.psd1"
connect-octoserver http://octohost.cloudapp.azure.com:8082 API-12345678901234567890
$raw = (Get-OctoVariable someproject somevariable | Where-Object { $_.Environment -eq "DEV" } )
$jsonfile = "c:\dataapi.json"
$raw.Value | ConvertFrom-Json | ConvertTo-Json | Out-File $jsonfile -Encoding UTF8
$data = Get-Content $jsonfile -Encoding UTF8 | ConvertFrom-Json
$data | ConvertTo-Json | Set-Content $jsonfile -Encoding UTF8
There is at least the following way to get a variable from a tenant in Octopus Deploy. I got this working with making OctopusClient.dll calls.
Add-Type -Path $OctopusClientDll #this should point to the dll
$Endpoint = New-Object Octopus.Client.OctopusServerEndpoint $octopusURI, $apiKey
$Repository = New-Object Octopus.Client.OctopusRepository $Endpoint
$TenantEditor = $Repository.Tenants.CreateOrModify($TenantName)
$Vars = $TenantEditor.Variables.Instance.LibraryVariables
$VarSet = $Vars[$COMMON_TENANT_VARSET_ID] # you need to know this
$VarTemplate = $VarSet.Templates | Where-Object -Property Name -eq "Tenant.VariableName"
$VariableValue = $VarSet.Variables[$varTemplate.Id].Value

Pompt if no input entered

If I just press enter without entering any variable.. it will spit out errors. What can I add to make it just repompt again?
mode con: cols=35 lines=5
while (1) {
$tag1 = Read-Host 'Enter tag # or Q to quit'
if ($tag1 -eq "Q") {
break;
}
mode con: cols=80 lines=46
cls
sc.exe \\$tag1 start RemoteRegistry;
cls
start-sleep -seconds 2
cls
$OSInfo = get-wmiobject -class win32_operatingsystem -computername $tag1;
$OSInfo | Format-Table -Property #{Name="OS Name";Expression={$_.Caption}} -AutoSize;
$OSInfo | Format-Table -Property #{Name="System Boot Time";Expression={$_.ConvertToDateTime($_.LastBootUpTime)}} -AutoSize;
$OSInfo | Format-Table -Property #{Name="OS Install Date";Expression={$_.ConvertToDateTime($_.InstallDate)}} -AutoSize;
"`n"
"Current Date & Time: $(Get-Date -Format G)";
"`n"
Get-WmiObject win32_computersystem -Computer $tag1 | Format-Table -Property #{Name="Username";Expression={$_.username}} -Autosize;
Get-EventLog system -computername $tag1 -InstanceId 2147489657 -Newest 10 | format-table EventID,TimeWritten,MachineName -AutoSize;
}
Couple of different ways:
$tag1 = $null
while (-not $tag1 ) {
$tag1 = Read-Host 'Enter tag # or Q to quit'
if ($tag1 -eq "Q") {
return;
}
}
mode con: cols=80 lines=46
cls
sc.exe \\$tag1 start RemoteRegistry;
cls
start-sleep -seconds 2
cls
$OSInfo = get-wmiobject -class win32_operatingsystem -computername $tag1;
$OSInfo | Format-Table -Property #{Name="OS Name";Expression={$_.Caption}} -AutoSize;
$OSInfo | Format-Table -Property #{Name="System Boot Time";Expression={$_.ConvertToDateTime($_.LastBootUpTime)}} -AutoSize;
$OSInfo | Format-Table -Property #{Name="OS Install Date";Expression={$_.ConvertToDateTime($_.InstallDate)}} -AutoSize;
"`n"
"Current Date & Time: $(Get-Date -Format G)";
"`n"
Get-WmiObject win32_computersystem -Computer $tag1 | Format-Table -Property #{Name="Username";Expression={$_.username}} -Autosize;
Get-EventLog system -computername $tag1 -InstanceId 2147489657 -Newest 10 | format-table EventID,TimeWritten,MachineName -AutoSize;
Or:
$GetTag = {
Switch (Read-Host 'Enter tag # or Q to quit')
{
'Q' {Return}
'' {.$GetTag}
default {$_}
}
}
$tag = &$GetTag
Just clear the variable and then loop until it is set.
$tag1 = ""
while (-not ($tag1)) {
$tag1 = Read-Host 'Enter tag # or Q to quit'
}

tst10 telnet scripting continuously

I am using this website (http://npr.me.uk/scripting.html) to connect to telnet and run command. It returns me some information. I need to get this info every 4 seconds. How do I do that? Now it runs but reconnects everytime, so I have to wait while it opens a connection and it takes much more than 4s. Bat file:
echo off
cls
if exist r1.txt del r1.txt
if exist r2.txt del r2.txt
tst10.exe /r:stats.txt /o:r1.txt /m
for /f "skip=30 tokens=*" %%A in (r1.txt) do echo %%A >> r2.txt
del r1.txt
start r2.txt
And stats file:
192.168.xxx.xxx
WAIT "login:"
SEND "myuser\m"
WAIT "Password:"
SEND "mypass\m"
WAIT ">"
SEND "mycommand\m"
WAIT ">"
Use Powershell to program using a csv file with the connections, I am using it for re-programming mfd's
I have a file mfd.txt and a script that reads it in.
I have a telnet script template to change the settings on the mfd and the powershell script creates custom scripts for each mfd and sets dns and hostname parameters. When run, a logfile is piped into a directory for checking later
Script is as follows:
#Process for updating devices quickly using telnet
#Check file exists
c:
cd 'C:\Resources\Telnet'
cls
$fileisthere = $false
$fileisthere = test-path 'C:\Resources\Telnet\mfds.csv'
if ($fileisthere -ne $true)
{
""
Write-Host ("There is no MFD import list C:\Resources\telnet\mfds.csv") | out-file -filepath $logfile -force
""
exit
}
Write-Host ("MFD import List is present")
# for each device in devices:
$mfds = import-csv 'C:\Resources\Telnet\mfds.csv'
foreach ($mfd in $mfds)
{
# ping device and check for response
$mfdname = $mfd.name
$mfdip = $mfd.ipaddress
$mfddns1 = $mfd.dns1
$mfddns2 = $mfd.dns2
$mfdhostname = $mfd.serial
""
Write-Host ("Updating device $($mfdname) on IP address $($Mfdip) ")
""
("Updating device $($mfdname) on IP address $($Mfdip) ") | out-file -filepath $logfile -Append -force
if(!(Test-Connection -Cn $mfdip -BufferSize 16 -Count 1 -ea 0 -quiet))
{
Write-Host ""
Write-Host ("MFD $($mfdname) is offline or not at this address")
Write-Host ""
"" | out-file $logfile -Append -force
("MFD $($mfdname) is offline or not at this address") | out-file $logfile -Append -force
"" | out-file $logfile -Append -force
}
else
{
#find replace script
# Device is present and add to script header
$tststring = "$($mfdip) 23"
$tstfile = "$($mfdname)-$($mfdip).txt"
$tstlogfile = "$($mfdname)-$($mfdip).log"
$tststring | out-file $tstfile -force
type dns.txt >> $tstfile
$location1 = "C:\Resources\telnet\$($tstfile)"
$change1 = get-content $location1
$change1 | ForEach-Object { $_ -replace "dns 1 server", "dns 1 server $($mfddns1)"} | Set-Content $location
$location2 = "C:\Resources\telnet\$($tstfile)"
$change2 = get-content $location2
$change2 | ForEach-Object { $_ -replace "dns 2 server", "dns 2 server $($mfddns2)"} | Set-Content $location
$location3 = "C:\Resources\telnet\$($tstfile)"
$change3 = get-content $location3
$change3 | ForEach-Object { $_ -replace "hostname ether name", "hostname ether name $($mfdhostname)"} | Set-Content $location
$location4 = "C:\Resources\telnet\$($tstfile)"
$change4 = get-content $location4
$change4 | ForEach-Object { $_ -replace "devicename name", "devicename name $($mfdhostname)"} | Set-Content $location
# Create variables for update
Write-Host ("Updating $($Mfdname) on IP Address $($mfdIP) ")
$parameter1 = "/r:$($tstfile)"
$parameter2 = "/o:$($tstlogfile)"
#& cmd tst10 $parameter1 $paremeter2
write-host ("$($tstfile) $($tstlogfile)")
new-item $tstfolder -Type directory
move-item $tstfile $tstfolder
move-item $tstlogfile $tstfolder -ErrorAction SilentlyContinue
}
}