I have a line of code that has some conflict in it and I just cannot see what it is.
Here is the program
$Date = Get-Date -Format MM-dd-yyyy-HH-mm-ss-tt
<#*****SQL Session Variables*****#>
$Username = "sa"
$Password = "xyz" | ConvertTo-SecureString -asPlainText -Force
$Credentials = New-Object System.Management.Automation.PSCredential($Username,$Password)
$DatabaseNames = Invoke-SQLcmd -Query "Select * From sys.databases WHERE Name NOT LIKE '%Master%' AND Name NOT LIKE '%Tempdb%' AND Name NOT LIKE '%Model%' AND Name NOT LIKE '%Msdb%';" -ServerInstance "localhost" | Select Name -ExpandProperty Name
Write-Host "****Database Names****" -ForeGroundColor Red -BackGroundColor Black
$DatabaseNames
"`n`n"
<#****Get Database Size****#>
Push-Location
Import-Module sqlps -disablenamechecking
Invoke-Sqlcmd -Query "select name, physical_name, size * 8.0 / 1024 size from sys.master_files WHERE Type_Desc NOT LIKE '%LOG%' AND Name NOT LIKE '%Master%' AND Name NOT LIKE '%Tempdb%' AND Name NOT LIKE '%Model%' AND Name NOT LIKE '%Msdb%';" -ServerInstance "localhost" | Select @{Label="Database Name";Expression={$_.name}}, @{Label="Location";Expression={$_.physical_name}}, @{Label="SIze (MB)";Expression={$_.size}}
Pop-Location
"`n"
Start-Sleep 4
<#****Backup Databases****#>
ForEach ($DatabaseName in $DatabaseNames)
{
$SQLBackupPath1 = "C:\T2\SQlBackup\"
$SQLBackupPath2 = "$DatabaseName"
$SQLBackupPath3 = "_"
$SQLBackupPath4 = $Date
$SQLBackupPath5 = "_.bak"
$SQLBackupPath = $SQLBackupPath1 + $SQLBackupPath2 + $SQLBackupPath3 + $SQLBackupPath4 + $SQLBackupPath5
$SQLBackupPath
Backup-SQLDatabase -ServerInstance localhost -Database $DatabaseName -BackupFile $SQLBackupPath -Credential $Credentials
Write-Host "Database Backup of " -NoNewLine
Write-Host "$DatabaseName" -ForeGroundColor Red -BackGroundColor Black -NoNewLine
Write-Host " has been completed"
"`n"
}
<#****Delete Databases****#>
ForEach ($DatabaseName in $DatabaseNames)
{
Push-Location
Import-Module sqlps -disablenamechecking
Invoke-Sqlcmd -Query "EXEC msdb.dbo.sp_delete_database_backuphistory @database_name = N'$DatabaseName';" -ServerInstance "localhost"
Invoke-Sqlcmd -Query "USE [master];" -ServerInstance "localhost"
Invoke-Sqlcmd -Query "ALTER DATABASE [$DatabaseName] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;" -ServerInstance "localhost"
Invoke-Sqlcmd -Query "DROP DATABASE [$DatabaseName];" -ServerInstance "localhost"
Pop-Location
Write-Host "Database: " -NoNewLine
Write-Host "$DatabaseName" -ForeGroundColor Red -BackGroundColor Black -NoNewLine
Write-Host " has been Dropped"
"`n"
}
Get-ChildItem -Path C:\T2\SQLBackup\ | Where-Object {$_.Name -match "ApOps*" } | Sort-Object LastWriteTime -Descending
If I move the final GetChildItem line under the first line $Date I get output. However if I use this in a loop or where it currently sits no results are returned. This makes me believe that there is some conflicting statement in the code. If so I cannot seem to find it and I am losing my mind looking for it. Please help.
You're being bitten by the output formatting, and being a bit careless with your output. Consider this, I'm in a directory with a couple of files:
List the files, simple and works fine:
PS D:\test> Get-ChildItem # list the files
Directory: D:\test
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 02/11/2016 07:01 1640 log.txt
-a---- 02/11/2016 07:01 0 testfile
Output an empty string, then list the files, simple and works fine. One blank line extra at the start:
PS D:\test> ""; Get-ChildItem
Directory: D:\test
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 02/11/2016 07:01 1640 log.txt
-a---- 02/11/2016 07:01 0 testfile
Get the string length, then list the files. Wait what? The output formatter is taking property you asked for from the first output it receives (string Length) and is then applying that to everything it receives (files) until the pipeline is empty:
PS D:\test> "" | select Length; Get-ChildItem # select string length, then...
Length # missing columns ??!!
------
0 # string length
1640 # file length
0 # file length
Get some property which doesn't exist, then list the files. This is the same idea, only this time it's not showing anything for the string or anything for the files, because Foobar
doesn't exist on either type:
PS D:\test> "" | select Foobar; Get-ChildItem # select property which doesn't exist
Foobar
------
# ???? this is your "no output"
You are doing this kind of thing - sending mixed types to the output pipeline. They still go to the output, if you captured them in variables or wrote them to files the data would be there, but the output formatter which tries to work out how to display them on the console takes the first thing it gets and formats the output against that, assuming you'll have a consistent output. And the first complex objects it gets come from your code here:
Invoke-Sqlcmd -Query "select name, physical_name, size * 8.0 / 1024 size from sys.master_files WHERE Type_Desc NOT LIKE '%LOG%' AND Name NOT LIKE '%Master%' AND Name NOT LIKE '%Tempdb%' AND Name NOT LIKE '%Model%' AND Name NOT LIKE '%Msdb%';" -ServerInstance "localhost" | Select @{Label="Database Name";Expression={$_.name}}, @{Label="Location";Expression={$_.physical_name}}, @{Label="SIze (MB)";Expression={$_.size}}
# where you select these properties for display:
# Database Name, Location, Size (MB)
# None of these properties exist on files or directories,
# so they don't get shown on screen.
Fix:
$x = Invoke-SqlCmd ___
$y = Get-ChildItem
$x | Format-Table
$y | Format-Table
Or use more Write-Host, or output to files.