Hello edwin,
Thanks for the Scripts. It really helped me reduced my day to day task. I managed to add backup ,disk space and database properties reports for SQL Server in one sheet.
It was working fine in excel 2010. I configured same reports in Excel 2013. It gets overwritten instead of adding another excel tab.
Can you please help me to resolve it?
Thanks in advanced. Below is my complete script:
$DirectoryToSaveTo = "C:\DBA_Weekly_Report\"
$date=Get-Date -format "yyyy-MM-d"
$Filename="Weekly_Report_$($date)"
$FromEmail="[email protected]"
$ToEmail="[email protected]"
$SMTPMail="[email protected]"
if (!(Test-Path -path "$DirectoryToSaveTo")) #create it if not existing
{
New-Item "$DirectoryToSaveTo" -type directory | out-null
}
$Computers = Get-Content "C:\DBA_Weekly_Report\Servers\SQL_Servers_WIN.txt"
# before we do anything else, are we likely to be able to save the file?
# if the directory doesn't exist, then create it
#Create a new Excel object using COM
$Excel = New-Object -ComObject Excel.Application
$Excel.visible = $True
$Excel = $Excel.Workbooks.Add()
$Sheet = $Excel.Worksheets.Item(1)
$sheet.Name = 'DiskSpace'
$Sheet.Activate() | Out-Null
#Create a Title for the first worksheet
$row = 1
$Column = 1
$Sheet.Cells.Item($row,$column)= 'Disk Space Information'
$range = $Sheet.Range("a1","h2")
$range.Merge() | Out-Null
$range.VerticalAlignment = -4160
#Give it a nice Style so it stands out
$range.Style = 'Title'
#Increment row for next set of data
$row++;$row++
#Save the initial row so it can be used later to create a border
$initalRow = $row
#Create a header for Disk Space Report; set each cell to Bold and add a background color
$Sheet.Cells.Item($row,$column)= 'Computername'
$Sheet.Cells.Item($row,$column).Interior.ColorIndex =48
$Sheet.Cells.Item($row,$column).Font.Bold=$True
$Column++
$Sheet.Cells.Item($row,$column)= 'DeviceID'
$Sheet.Cells.Item($row,$column).Interior.ColorIndex =48
$Sheet.Cells.Item($row,$column).Font.Bold=$True
$Column++
$Sheet.Cells.Item($row,$column)= 'VolumeName'
$Sheet.Cells.Item($row,$column).Interior.ColorIndex =48
$Sheet.Cells.Item($row,$column).Font.Bold=$True
$Column++
$Sheet.Cells.Item($row,$column)= 'TotalSizeGB'
$Sheet.Cells.Item($row,$column).Interior.ColorIndex =48
$Sheet.Cells.Item($row,$column).Font.Bold=$True
$Column++
$Sheet.Cells.Item($row,$column)= 'UsedSpaceGB'
$Sheet.Cells.Item($row,$column).Interior.ColorIndex =48
$Sheet.Cells.Item($row,$column).Font.Bold=$True
$Column++
$Sheet.Cells.Item($row,$column)= 'FreeSpaceGB'
$Sheet.Cells.Item($row,$column).Interior.ColorIndex =48
$Sheet.Cells.Item($row,$column).Font.Bold=$True
$Column++
$Sheet.Cells.Item($row,$column)= '%Free'
$Sheet.Cells.Item($row,$column).Interior.ColorIndex =48
$Sheet.Cells.Item($row,$column).Font.Bold=$True
$Column++
$Sheet.Cells.Item($row,$column)= 'State'
$Sheet.Cells.Item($row,$column).Interior.ColorIndex =48
$Sheet.Cells.Item($row,$column).Font.Bold=$True
#Set up a header filter
$headerRange = $Sheet.Range("a3","h3")
$headerRange.AutoFilter() | Out-Null
#Increment Row and reset Column back to first column
$row++
$Column = 1
$critical=0
$warning=0
$good=0
#Get the drives and filter out CD/DVD drives
foreach ($computer in $Computers)
{
$diskDrives = Get-WmiObject win32_LogicalDisk -Filter "DriveType='3'" -ComputerName $computer
#Process each disk in the collection and write to spreadsheet
ForEach ($disk in $diskDrives) {
$Sheet.Cells.Item($row,1)= $disk.__Server
$Sheet.Cells.Item($row,2)= $disk.DeviceID
$Sheet.Cells.Item($row,3)= $disk.VolumeName
$Sheet.Cells.Item($row,4)= [math]::Round(($disk.Size /1GB),2)
$Sheet.Cells.Item($row,5)= [math]::Round((($disk.Size - $disk.FreeSpace)/1GB),2)
$Sheet.Cells.Item($row,6)= [math]::Round(($disk.FreeSpace / 1GB),2)
$Sheet.Cells.Item($row,7)= ("{0:P}" -f ($disk.FreeSpace / $disk.Size))
$FreeSPACEPERCENTAGE = [Math]::round((($disk.FreeSpace/$disk.Size) * 100))
#Determine if disk needs to be flagged for warning or critical alert
If ($FreeSPACEPERCENTAGE -lt 10)
{
$Sheet.Cells.Item($row,8) = "Critical"
$critical++
#Check to see if space is near empty and use appropriate background colors
$range = $Sheet.Range(("A{0}" -f $row),("H{0}" -f $row))
$range.Select() | Out-Null
#Critical threshold
$range.Interior.ColorIndex = 3
}
ElseIf ($FreeSPACEPERCENTAGE -lt 15)
{
$Sheet.Cells.Item($row,8) = "Warning"
$range = $Sheet.Range(("A{0}" -f $row),("H{0}" -f $row))
$range.Select() | Out-Null
$warning++
$range.Interior.ColorIndex = 6
}
Else
{
$Sheet.Cells.Item($row,8) = "Good"
$good++
}
$row++
}
}
#Add a border for data cells
$row--
$dataRange = $Sheet.Range(("A{0}" -f $initalRow),("H{0}" -f $row))
7..12 | ForEach {
$dataRange.Borders.Item($_).LineStyle = 1
$dataRange.Borders.Item($_).Weight = 2
}
#Auto fit everything so it looks better
$usedRange = $Sheet.UsedRange
$usedRange.EntireColumn.AutoFit() | Out-Null
$critical
$warning
$good
$sheet = $excel.Worksheets.Item(1)
$row++;$row++
$beginChartRow = $Row
$Sheet.Cells.Item($row,$Column) = 'Critical'
$Column++
$Sheet.Cells.Item($row,$Column) = 'Warning'
$Column++
$Sheet.Cells.Item($row,$Column) = 'Good'
$Column = 1
$row++
#Critical formula
$Sheet.Cells.Item($row,$Column)=$critical
$Column++
#Warning formula
$Sheet.Cells.Item($row,$Column)=$warning
$Column++
#Good formula
$Sheet.Cells.Item($row,$Column)= $good
$endChartRow = $row
$chartRange = $Sheet.Range(("A{0}" -f $beginChartRow),("C{0}" -f $endChartRow))
##Add a chart to the workbook
#Open a sheet for charts
$temp = $sheet.Charts.Add()
$temp.Delete()
$chart = $sheet.Shapes.AddChart().Chart
$sheet.Activate()
#Configure the chart
##Use a 3D Pie Chart
$chart.ChartType = 70
$chart.Elevation = 40
#Give it some color
$sheet.Shapes.Item("Chart 1").Fill.ForeColor.TintAndShade = .34
$sheet.Shapes.Item("Chart 1").Fill.ForeColor.ObjectThemeColor = 5
$sheet.Shapes.Item("Chart 1").Fill.BackColor.TintAndShade = .765
$sheet.Shapes.Item("Chart 1").Fill.ForeColor.ObjectThemeColor = 5
$sheet.Shapes.Item("Chart 1").Fill.TwoColorGradient(1,1)
#Set the location of the chart
$sheet.Shapes.Item("Chart 1").Placement = 3
$sheet.Shapes.Item("Chart 1").Top = 30
$sheet.Shapes.Item("Chart 1").Left = 600
$chart.SetSourceData($chartRange)
$chart.HasTitle = $True
$chart.ApplyLayout(6,69)
$chart.ChartTitle.Text = "Disk Space Report"
$chart.ChartStyle = 26
$chart.PlotVisibleOnly = $False
$chart.SeriesCollection(1).DataLabels().ShowValue = $True
$chart.SeriesCollection(1).DataLabels().Separator = ("{0}" -f [char]10)
$chart.SeriesCollection(1).DataLabels().Position = 2
#Critical
$chart.SeriesCollection(1).Points(1).Format.Fill.ForeColor.RGB = 255
#Warning
$chart.SeriesCollection(1).Points(2).Format.Fill.ForeColor.RGB = 65535
#Good
$chart.SeriesCollection(1).Points(3).Format.Fill.ForeColor.RGB = 5287936
#Hide the data
$chartRange.EntireRow.Hidden = $True
$Sheet.UsedRange.EntireColumn.AutoFit()
#############################################################2nd Sheet
$Sheet = $Excel.Worksheets.Item(2)
$sheet.Name = 'Backup'
$Sheet.Activate() | Out-Null
$date = Get-Date -format f
$cells=$Sheet.Cells
#Create a Title for the first worksheet
$row = 1
$Column = 1
$Sheet.Cells.Item($row,$column)= "Backup Report $date"
$range = $Sheet.Range("a1","h2")
$range.Merge() | Out-Null
$range.VerticalAlignment = -4160
#Give it a nice Style so it stands out
$range.Style = 'Title'
#Increment row for next set of data
$row++;$row++
#define some variables to control navigation
$row=3
$col=1
#insert column headings
$cells.item($row,$col)="Instance Name"
$cells.item($row,$col).font.size=16
$cells.item($row,$col).HorizontalAlignment = -4108
$col++
$cells.item($row,$col)="DATABASE NAME"
$cells.item($row,$col).font.size=16
$cells.item($row,$col).HorizontalAlignment = -4108
$col++
$cells.item($row,$col)="RECOVERY MODEL"
$cells.item($row,$col).font.size=16
$cells.item($row,$col).HorizontalAlignment = -4108
$col++
$cells.item($row,$col)="LAST FULL BACKUP"
$cells.item($row,$col).font.size=16
$cells.item($row,$col).HorizontalAlignment = -4108
$col++
$cells.item($row,$col)="LAST Differential BACKUP"
$cells.item($row,$col).font.size=16
$cells.item($row,$col).HorizontalAlignment = -4108
$col++
$cells.item($row,$col)="LAST LOG BACKUP"
$cells.item($row,$col).font.size=16
$cells.item($row,$col).HorizontalAlignment = -4108
$col++
$cells.item($row,$col)="FULL BACKUP AGE(DAYS)"
$cells.item($row,$col).font.size=16
$cells.item($row,$col).HorizontalAlignment = -4108
$col++
$cells.item($row,$col)="DIFF BACKUP AGE(DAYS)"
$cells.item($row,$col).font.size=16
$cells.item($row,$col).HorizontalAlignment = -4108
$col++
$cells.item($row,$col)="LOG BACKUP AGE(HOURS)"
$cells.item($row,$col).font.size=16
$cells.item($row,$col).HorizontalAlignment = -4108
$col++
# Load SMO extension
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | Out-Null;
# Get List of sql servers to check
$sqlservers = Get-Content 'C:\DBA_Weekly_Report\Servers\SQL_Servers_SQL.txt';
# Loop through each sql server from sqlservers.txt
foreach($sqlserver in $sqlservers)
{
# Create an SMO Server object
$srv = New-Object "Microsoft.SqlServer.Management.Smo.Server" $sqlserver;
$dbs = $srv.Databases
# For each jobs on the server
foreach($db in $dbs)
{
if ($db.Name -ne "tempdb") #We do not need the backup information for the tempdb database
{
$Reco_Model=$db.RecoveryModel.Tostring()
$NumDaysSinceLastFullBackup = ((Get-Date) - $db.LastBackupDate).Days #We use Date Math to extract the number of days since the last full backup
$NumDaysSinceLastLogBackup = ((Get-Date) - $db.LastLogBackupDate).TotalHours #Here we use TotalHours to extract the total number of hours
$NumDaysSinceLastDiffBackup = ((Get-Date) - $db.LastDifferentialBackupDate).Days
if($db.LastBackupDate -eq "1/1/0001 12:00 AM") #This is the default dateTime value for databases that have not had any backups
{
$fullBackupDate="Never been backed up"
$fgColor3="red"
}
else
{
$fullBackupDate="{0:g}" -f $db.LastBackupDate
}
if($db.LastDifferentialBackupDate -eq "1/1/0001 12:00 AM") #This is the default dateTime value for databases that have not had any backups
{
$DiffBackupDate="Never been backed up"
$NumDaysSinceLastDiffBackup="Never been backed up"
$fgColor3="red"
}
else
{
$DiffBackupDate="{0:g}" -f $db.LastDifferentialBackupDate
$NumDaysSinceLastDiffBackup = ((Get-Date) - $db.LastDifferentialBackupDate).Days
}
#We use the .ToString() Method to convert the value of the Recovery model to string and ignore Log backups for databases with Simple recovery model
if ($db.RecoveryModel.Tostring() -eq "SIMPLE")
{
$logBackupDate="Simple Recovery Model"
$NumDaysSinceLastLogBackup="Simple Recovery Model"
}
else
{
if($db.LastLogBackupDate -eq "1/1/0001 12:00 AM")
{
$logBackupDate="Never been backed up"
}
else
{
$logBackupDate= "{0:g}" -f $db.LastLogBackupDate
}
}
#Define your service-level agreement in terms of days here
if ($NumDaysSinceLastFullBackup -gt 7)
{
$fgColor = 3
}
else
{
$fgColor = 0
}
# Success is Green
$row++
$col=1
$cells.item($Row,$col).HorizontalAlignment = -4108
$cells.item($Row,$col)=$sqlserver
$col++
$cells.item($Row,$col).HorizontalAlignment = -4108
$cells.item($Row,$col)=$db.Name
$col++
$cells.item($Row,$col).HorizontalAlignment = -4108
$cells.item($Row,$col)=$Reco_Model
$col++
$cells.item($Row,$col).HorizontalAlignment = -4108
$cells.item($Row,$col)=$fullBackupDate
$col++
#Set colour of cells for Disabled Jobs to Grey
$cells.item($Row,$col).HorizontalAlignment = -4108
$cells.item($Row,$col)=$DiffBackupDate
$col++
$cells.item($Row,$col).HorizontalAlignment = -4108
$cells.item($Row,$col)=$logBackupDate
$col++
$cells.item($Row,$col).HorizontalAlignment = -4108
$cells.item($Row,$col)=$NumDaysSinceLastFullBackup
$Sheet.Cells.item($intRow, 4).Interior.ColorIndex = $fgColor
$col++
$cells.item($Row,$col).HorizontalAlignment = -4108
$cells.item($Row,$col)=$NumDaysSinceLastDiffBackup
$col++
$cells.item($Row,$col).HorizontalAlignment = -4108
$cells.item($Row,$col)=$NumDaysSinceLastLogBackup
#Set teh Fill Colour for Time Cells
}
}
}
$Sheet.UsedRange.EntireColumn.AutoFit()
#############################################################3rd Sheet
$Sheet = $Excel.Worksheets.Item(3)
$sheet.Name = 'SQL_Server_Database_Properties '
$Sheet.Activate() | Out-Null
$date = Get-Date -format f
$cells=$Sheet.Cells
$Sheet.Cells.Item($row,$column)= "Database Properties Report $date"
$range = $Sheet.Range("a1","h2")
$range.Merge() | Out-Null
$range.VerticalAlignment = -4160
#Give it a nice Style so it stands out
$range.Style = 'Title'
#Increment row for next set of data
$row++;$row++
#define some variables to control navigation
$row=3
$col=1
#insert column headings
$cells.item($row,$col)="Instance Name"
$cells.item($row,$col).font.size=16
$cells.item($row,$col).HorizontalAlignment = -4108
$col++
$cells.item($row,$col)="DATABASE NAME"
$cells.item($row,$col).font.size=16
$cells.item($row,$col).HorizontalAlignment = -4108
$col++
$cells.item($row,$col)="COLLATION"
$cells.item($row,$col).font.size=16
$cells.item($row,$col).HorizontalAlignment = -4108
$col++
$cells.item($row,$col)="COMPATIBILITY LEVEL"
$cells.item($row,$col).font.size=16
$cells.item($row,$col).HorizontalAlignment = -4108
$col++
$cells.item($row,$col)="AUTOSHRINK"
$cells.item($row,$col).font.size=16
$cells.item($row,$col).HorizontalAlignment = -4108
$col++
$cells.item($row,$col)="RECOVERY MODEL"
$cells.item($row,$col).font.size=16
$cells.item($row,$col).HorizontalAlignment = -4108
$col++
$cells.item($row,$col)="SIZE (MB)"
$cells.item($row,$col).font.size=16
$cells.item($row,$col).HorizontalAlignment = -4108
$col++
$cells.item($row,$col)="SPACE AVAILABLE (MB)"
$cells.item($row,$col).font.size=16
$cells.item($row,$col).HorizontalAlignment = -4108
$col++
# Load SMO extension
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | Out-Null;
# Get List of sql servers to check
$sqlservers = Get-Content 'C:\DBA_Weekly_Report\Servers\SQL_Servers_SQL.txt';
# Loop through each sql server from sqlservers.txt
foreach($instance in $sqlservers)
{
# Create an SMO connection to the instance
$s = New-Object ('Microsoft.SqlServer.Management.Smo.Server') $instance
$dbs = $s.Databases
#$dbs | SELECT Name, Collation, CompatibilityLevel, AutoShrink,RecoveryModel, Size, SpaceAvailable
foreach($db in $dbs)
{
#Divide the value of SpaceAvailable by 1KB
$dbSpaceAvailable = $db.SpaceAvailable/1KB
#Format the results to a number with three decimal places
$dbSpaceAvailable = "{0:N3}" -f $dbSpaceAvailable
#Change the background color of the Cell depending on the AutoShrink property value
if ($db.AutoShrink -eq "True")
{
$fgColor = 3
}
else
{
$fgColor = 0
}
if ($db.RecoveryModel.Tostring() -eq "FULL")
{
$RecoveryModel="N/A"
}
else
{
$RecoveryModel ="not applicabale"
}
#Change the background color of the Cell depending on the SpaceAvailable property value
if ($dbSpaceAvailable -lt 1.00)
{
$fgColor = 3
}
else
{
$fgColor = 0
}
# Success is Green
$row++
$col=1
$cells.item($Row,$col).HorizontalAlignment = -4108
$cells.item($Row,$col)=$instance
$col++
$cells.item($Row,$col).HorizontalAlignment = -4108
$cells.item($Row,$col)=$db.Name
$col++
$cells.item($Row,$col).HorizontalAlignment = -4108
$cells.item($Row,$col)=$db.COLLATION
$col++
$cells.item($Row,$col).HorizontalAlignment = -4108
$cells.item($Row,$col)=$db.CompatibilityLevel
$col++
$cells.item($Row,$col).HorizontalAlignment = -4108
$cells.item($Row,$col)=$db.AutoShrink
$Sheet.Cells.item($intRow, 5).Interior.ColorIndex = $fgColor
$col++
$cells.item($Row,$col).HorizontalAlignment = -4108
$cells.item($Row,$col)=$db.RecoveryModel.Tostring()
$col++
$cells.item($Row,$col).HorizontalAlignment = -4108
$cells.item($Row,$col)="{0:N3}" -f $db.Size
$col++
$cells.item($Row,$col).HorizontalAlignment = -4108
$cells.item($Row,$col)=$dbSpaceAvailable
$Sheet.Cells.item($intRow, 8).Interior.ColorIndex = $fgColor
#Set teh Fill Colour for Time Cells
}
}
$Sheet.UsedRange.EntireColumn.AutoFit()
$filename = "$DirectoryToSaveTo$filename.xlsx"
if (test-path $filename )
{
rm $filename
} #delete the file if it already exists
$erroractionpreference = "SilentlyContinue"
$Sheet.UsedRange.EntireColumn.AutoFit()
$Excel.SaveAs($filename) #save as an XML Workbook (xslx)
$Excel.Saved = $True
$Excel.Close()
$Excel.DisplayAlerts = $False
$Excel.quit()
Function sendEmail([string]$emailFrom, [string]$emailTo, [string]$subject,[string]$body,[string]$smtpServer,[string]$filePath)
{
#initate message
$email = New-Object System.Net.Mail.MailMessage
$email.From = $emailFrom
$email.To.Add($emailTo)
$email.Subject = $subject
$email.Body = $body
# initiate email attachment
$emailAttach = New-Object System.Net.Mail.Attachment $filePath
$email.Attachments.Add($emailAttach)
#initiate sending email
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($email)
}
#Call Function
$message = @"
Hi Team,
Please find attached excel sheet for Weekly report.
Autogenerated Email!!! Please do not reply.
Thank you.
"@
$date=get-date
sendEmail -emailFrom $fromEmail -emailTo $ToEmail -subject "Weekly Reports -$($date)" -body $message -smtpServer $SMTPMail -filePath $filename
Regards,
Shreyas K. Rane
|