PowerShell – Send SMTP Email and Add Message Body Sent from Script Using PowerShell

This is the first PowerShell script that I wrote. I was inspired to start using PowerShell after I met with one of our developers. He creates scripts to automate repetitive​​ administrative tasks (e.g. daily system health check). I asked the developer if he learned writing PowerShell from a book or a training class. ​​ He said that he neither read any book nor attend a PowerShell training class. Instead, he told me that he just knows what he wanted to achieve and then he searched the internet on how to achieve it. In other words, he just Googled the codes.

 

I always wanted to learn PowerShell. ​​ As a DBA, I think it would be beneficial to use this powerful tool. I read books about​​ PowerShell and did the exercises but I feel I never progressed and I’m still not able to create anything.​​ 

 

So I tried to do what the developer told me. First, I started to think what I want to achieve and that is to send disk space usage of our Database Servers to my email. ​​ This is so that I won’t have to login to our DB servers everytime.

Below is the PowerShell script.

 

#.SYNOPSIS

# Sends Daily Disk Space Usage Report

#

#EXAMPLE

#.\Send-DiskSpaceUsageReport.ps1

#

 

$smtpServer​​ =​​ "Fsmtp.our.property.com.sg"

$smtpFrom​​ =​​ "NXPOPARVRAPPLE@nhg.local"

$smtpTo​​ =​​ "valenciajec@ncs.com.sg"

$messageSubject​​ =​​ "OPAS TTSH Daily Disk Space Usage Report"

 

[string]$messagebody​​ =​​ ""

 

$logs​​ =​​ Get-Content​​ D:\DBA\DB_Health_Checks_Node1\6.DiskUsage_Node1_/TTSH.txt,​​ \\10.240.xx.xx\d$\DBA\DB_Health_Checks_Node2\2.DiskUsage_Node2_TTSH.txt

 

foreach​​ ($log​​ in​​ $logs​​ )

{

 ​​ ​​ ​​​​ $messagebody​​ =​​ $messagebody​​ +​​ $log​​ +​​ "`r`n"

}

 

$smtp​​ =​​ New-Object​​ Net.Mail.SmtpClient($smtpServer)

$smtp.Send($smtpFrom,$smtpTo,$messagesubject,$messagebody)​​ 

 

 

This script will add a message body to emails sent from script. I have a SQL Server Agent job that generates the text file that contains the disk space usage report. So basically, the PowerShell script will get the contents of the text​​ file and add it to the message body of the email.

 

 

 

 

The next step is to​​ create a Scheduled Task​​ to run the PowerShell script.

 

  • Open Task Scheduler

 

Open Task Scheduler and Create a new task. Name it and set your security options.  Check "Run with highest​​ privileges" as our scripts need to run as admin. Choose “Run whether user is logged on or not.”

 

 

 

 

 

 

  • Set Triggers

 

 

 

 

  • Create your Action

 

Click on Actions tab and click New.

Action: Start a program

Program /script: PowerShell.exe

 

You don’t need to​​ put a path as it should already be on your system

 

  • Set Argument

 

You first need to set the​​ ExecutionPolicy. There are two options to do that either you set the ExecutionPolicy on the machine or on a per-script basis. I will only set it on a per-script basis but If you want to set the execution policy globally, you can issue this command from within PowerShell.

 

Set-ExecutionPolicy Unrestricted

 

To set the ExecutionPolicy on a​​ per script basis, put the line below on the Add arguments (change the file name to​​ your script’s file name.ps1)

 

 

 ​​ ​​ ​​ ​​ ​​ ​​​​ -ExecutionPolicy Bypass -File D:\DBA\Scripts\PowerShell\Send-DiskSpaceUsageReport.ps1

 

  

  Indicate the path of your script in the Start in(optional)

 

 

 

 

  • Change Settings

 

I encountered the error “Launch request​​ ignored, instance already running (154257)”and the task failed to run. ​​ To resolve this issue, I changed the setting to “Stop the existing instance” ​​ 

 

 

 

  • Save and Test

 

 

 

Knowledge worth sharing...Share on linkedin
Linkedin
Share on facebook
Facebook
Share on google
Google
Share on twitter
Twitter

SQL Server – Get the Table Structure Using T-SQL

When you are writing a SELECT statement and you just want to limit the number of columns, you would use the​​ sp_help​​ stored procedure to research the underlying table structure as shown​​ below.

 

​​ 

 

 

The​​ sp_help​​ system stored procedure will return all the data about a particular table when you pass the table name into the stored procedure.

 

But If you don't want to sort through all that information, it is possible to get only the names of the columns by executing a query that selects all columns with a false​​ WHERE​​ clause as shown below.

 

SELECT​​ *

FROM​​ [HumanResources].[Employee]

WHERE​​ 1=0

 

 

 

This query tells SQL Server to return all the columns and rows where one equals zero. Because one can never equal zero, SQL Server will return the column names from the table with no data.

Knowledge worth sharing...Share on linkedin
Linkedin
Share on facebook
Facebook
Share on google
Google
Share on twitter
Twitter

SQL Server – Check Recent Backup of All Your SQL Server Databases

Do you have a recent backup of all your SQL Server databases? Use the script below to check ​​ if you have.

 

 

SELECT​​ B.name​​ as​​ Database_Name,​​ ISNULL(STR(ABS(DATEDIFF(day,​​ GetDate(),​​ 

MAX(Backup_finish_date)))),​​ 'NEVER')​​ as​​ DaysSinceLastBackup,

ISNULL(Convert(char(10),​​ MAX(backup_finish_date),​​ 101),​​ 'NEVER')​​ as​​ LastBackupDate

FROM​​ master.dbo.sysdatabases​​ B​​ LEFT​​ OUTER​​ JOIN​​ msdb.dbo.backupset A​​ 

ON​​ A.database_name​​ =​​ B.name​​ AND​​ A.type​​ =​​ 'D'​​ GROUP​​ BY​​ B.Name​​ ORDER​​ BY​​ B.name

 

 

Knowledge worth sharing...Share on linkedin
Linkedin
Share on facebook
Facebook
Share on google
Google
Share on twitter
Twitter

SQL Server – Get Last Modified Function

To get the last modified function​​ date, execute the script below.

 

 

SELECT​​ name,

type_desc

 create_date,

modify_date

FROM​​ sys.objects​​ 

WHERE​​ RIGHT(type_desc,​​ 8)​​ =​​ 'FUNCTION'

ORDER​​ BY​​ modify_date​​ DESC

 

 

 

Knowledge worth sharing...Share on linkedin
Linkedin
Share on facebook
Facebook
Share on google
Google
Share on twitter
Twitter

SQL Server – Get Physical Memory of Database Server

Below is a script that you can use to​​ retrieve​​ your​​ DB Server’s​​ Physical Memory

 

 

CREATE​​ TABLE​​ #SVer(ID​​ int, ​​​​ Name ​​ sysname,​​ Internal_Value​​ int,​​ Value​​ nvarchar(512))

INSERT​​ #SVer​​ exec​​ master.dbo.xp_msver

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ 

SELECT​​ *

FROM​​ #SVer

WHERE​​ Name​​ =​​ 'PhysicalMemory'

GO

 

DROP​​ TABLE​​ #SVer​​ 

 

 

 

Knowledge worth sharing...Share on linkedin
Linkedin
Share on facebook
Facebook
Share on google
Google
Share on twitter
Twitter

SQL Server – Get Transaction Log Size and Log Space Used

Use the following T-SQL script to get the transaction log size and log space used of your database.

 

 

SELECT​​ DB_NAME(database_id)​​ AS​​ DatabaseName​​ ,

CAST((​​ total_log_size_in_bytes​​ /​​ 1048576.0​​ )​​ AS​​ DECIMAL(10,​​ 1))

AS​​ TotalLogSizeMB​​ ,

CAST((​​ used_log_space_in_bytes​​ /​​ 1048576.0​​ )​​ AS​​ DECIMAL(10,​​ 1))

AS​​ LogSpaceUsedMB​​ ,

CAST(used_log_space_in_percent​​ AS​​ DECIMAL(10,​​ 1))​​ AS​​ LogSpaceUsedPercent

FROM​​ sys.dm_db_log_space_usage;

 

 

Knowledge worth sharing...Share on linkedin
Linkedin
Share on facebook
Facebook
Share on google
Google
Share on twitter
Twitter

SQL Server – Pending Disk IO Count

Below is a script to see the number of pending disk IO. The ideal value is 0.​​ This value indicates the number of pending I/Os that are waiting to be completed. Each scheduler has a list of pending I/Os that are checked to determine whether they have been completed every time there is a context switch. The count is incremented when the request is inserted. This count is decremented when the request is completed.

 

 

SELECT​​ SUM(pending_disk_io_count)​​ AS​​ [Number of pending I/Os]​​ 

FROM​​ sys.dm_os_schedulers

 

 

Knowledge worth sharing...Share on linkedin
Linkedin
Share on facebook
Facebook
Share on google
Google
Share on twitter
Twitter

SQL Server – Check Constraint Status

Below is a script that you can use to check the constraint status of all your tables in the database.

 

SELECT​​ (CASE​​ 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ WHEN​​ OBJECTPROPERTY(CONSTID,​​ 'CNSTISDISABLED')​​ =​​ 0​​ THEN​​ 'ENABLED'

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ ELSE​​ 'DISABLED'

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ END)​​ AS​​ STATUS,

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ OBJECT_NAME(CONSTID)​​ AS​​ CONSTRAINT_NAME,

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ OBJECT_NAME(FKEYID)​​ AS​​ TABLE_NAME,

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ COL_NAME(FKEYID,​​ FKEY)​​ AS​​ COLUMN_NAME,

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ OBJECT_NAME(RKEYID)​​ AS​​ REFERENCED_TABLE_NAME,

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ COL_NAME(RKEYID,​​ RKEY)​​ AS​​ REFERENCED_COLUMN_NAME

 ​​ ​​​​ FROM​​ SYSFOREIGNKEYS

ORDER​​ BY​​ TABLE_NAME,​​ CONSTRAINT_NAME,REFERENCED_TABLE_NAME,​​ KEYNO

 

 

 

Output:

 

Knowledge worth sharing...Share on linkedin
Linkedin
Share on facebook
Facebook
Share on google
Google
Share on twitter
Twitter

SQL Server – Msg 1468, Level 16, State 1, Line 1

ERROR

 

Msg 1468, Level 16, State 1, Line 1

The operation cannot be performed on database "DBName" because it is involved in a database mirroring session or an availability group. Some operations are not allowed on a database that is participating in a database mirroring session or in an availability group.

Msg 5069, Level 16, State 1, Line 1

ALTER DATABASE statement failed.

 

 

Below are the steps I did to resolve the error.

 

  • Remove DBName from AAG

  • Enable Service Broker

ALTER​​ DATABASE​​ DBName​​ SET​​ ENABLE_BROKER;

 

  • Verify Service Broker Enabled

SELECT​​ is_broker_enabled​​ FROM​​ sys.databases​​ WHERE​​ name​​ =​​ 'DBName';

 

  • Add DBName to AAG

 

 

 

 

ue]

Knowledge worth sharing...Share on linkedin
Linkedin
Share on facebook
Facebook
Share on google
Google
Share on twitter
Twitter

SQL Server – Adding a Database to AlwaysOn Availability Group

I usually restore the backup file to the secondary replica WITH NORECOVERY state before I add database to AlwaysOn Availability Group (AAG).

 

The following are the steps to add a​​ database to AAG.

 

 

  • Expand​​ Availability Groups. Right-click​​ Availability Database. Choose​​ Add Database.

 

 

 

  • Click​​ Next.

 

 

 

  • Tick the database that you want to add. You will notice that under status​​ columm, the message is “Meets​​ prerequisites”. This is because I have already restored the database with norecovery status in the secondary replica.

 

 

 

 

  • Choose​​ Join Only.

 

 

 

  • Connect​​ to existing secondary replicas.

 

 

 

 

  • Click​​ Next.

 

 

 

 

  • Click​​ Finish.

 

 

 

 

  • Click​​ Close.

 


 

]

Knowledge worth sharing...Share on linkedin
Linkedin
Share on facebook
Facebook
Share on google
Google
Share on twitter
Twitter