SAPIEN – Windows PowerShell Class on Disc V2…

(from the SAPIEN Newsletter – June 2 2010)

Windows PowerShell Class on Disc V2

You asked for it and we got it! The newly released ScriptingAnswers.com Windows PowerShell V2: What’s New Class-on-Disc is the fourth video in our Windows PowerShell self paced training series.  A perfect complement to our original training set, this disk covers what has changed and been added to PowerShell V2.  This is not for the novice.  This is meant as an extension to those who have completed the Fundamentals, Intermediate and Advanced Class-on-Disc series, or have an advanced working knowledge of Windows PowerShell.

Get your copy today at scriptingoutpost.com

HIGHLY RECOMMENDED!!!

Advertisements
Posted in Uncategorized | Leave a comment

SQLLunch.com Livemeeting – SQL Server & PowerShell working with Databases…

Event Date: 

Tuesday, May 25, 2010 – 12:30pm EST / 11:30am CST

Please join me at SQLLunch,com with host Patrick DeBlanc in a livemeeting 30 minutes session. To connect click at this link on the day of the session: http://www.sqllunch.com/Meeting.aspx?lunchid=18
We’ll be looking into using SQLPS.exe how to work with databases on multiple SQL Servers. See How-To Configure your PowerShell profile to make your scripting environment more productive. This session will have a lot of samples".

Posted in Uncategorized | Leave a comment

Just made SAPIEN MVP …

First was becoming a Microsoft MVP and now SAPIEN MVP.

Thanks to SAPIEN Technologies for the award,  Please, check the others awardees at their MVP site:

http://www.primaltools.com/mvp

Posted in Uncategorized | Leave a comment

Idera – SQL Virtual Database working with SQL Server and PowerShell…

 

Get PowerShell V2

Get it Here!!

 

Yes, Idera has done it again! This new product may make you think of all possibilities to help you get information from any SQL backups without restoring.  Please take a look at Pinal Dave (SQL MVP) blog on “Idera Virtual database”.  It’s an excellent blog!!

Now, using the Idera “SQL Virtual database” application is very simple to use.  Here’s a quick sample using the GUI:

Perfect, I got my first SQL Virtual Database connected and accessible on SSMS.  Here’s some of the things I found out that when I created my SQL Virtual Database:

1. It will not consume any of your disk space.

2. if you don’t want to copy over a database to your local drive then you can create a SQLvdb from a network drive.

3. The SQL Virtual database can be accessible from your SQL Server Management Studio (SSMS) like a normal database.

4. If you update any records in a table, it won’t be saved when you disconnect from the virtual database.

5. And, it does provide a command-line version “SQLvdbCLI.exe”, which you can run from PowerShell.

6. It’s proven is faster to create a virtual database than to do a restore and without taking over your disk space.

Now, let see how we can use SQL Virtual Database command-line in PowerShell.  Use the “SQLvdbCLI.exe” at the console prompt  using the “-help parameter to access the text help documentation.  Again, this command-line help is only available at the prompt.

Let me give you an example in how to create a SQL Virtual Database using the command-line:

SQLvdbCLI -Create -Full Z:\Databases\backup\Developer.bak -Instance MAX-PCWIN1 -Db Developer_Virtual

 

Now, let use SQLPS to connect to our local SQL Server and confirm that we can get to our SQL Virtual Database “Developer_Virtual”:

Although, in above picture I’m doing CD “Change Directory” to show that you can navigate into my SQL Virtual Database, you can have navigate directly to the tables folder by using one-liner from the PS> prompt:

PS> CD SQLSERVER:\SQL\MAX-PCWIN1\Default\Databases\Developer_Virtual\tables

PS> Dir | Select –first 10   #- to list the first 10 tables

But, if you have use SQLPS loading the SQL Server snapins and provider from your PowerShell Console (not SQLPS.exe by itself).  Then, you can query directly to the database using the cmdlet “Invoke-SQLCmd” and get instant results:

So, as you can see this tool can be a very useful not only to the administrator but also for the developer.

Please, go ahead, download the evaluation and give it a test drive.  I’m sure you will love it too and you will find a practical way to use it with PowerShell.  I definitely GUARANTEE it’s a good match and it l save you time when automating a task.

Posted in Uncategorized | Leave a comment

Code-Snippet: SQLPS – SQL Server PowerShell User Authentications…

Using SQLPS or if you have manage to include the SQL Server 2008 PowerShell snapins and provider to load from your user profile.  The following PowerShell code snippet will get you connected to you local SQL Server using your trusted integrated Windows Authentication:

$SQLname = "ServerName"
$MySQL = new-object('Microsoft.SqlServer.Management.Smo.Server') $SQLname


Now, you are probably wondering, how can I use SQL Authentication to connect to my database?  And, here’s how:

$SQLname = "ServerName"
$MySQL = new-object('Microsoft.SqlServer.Management.Smo.Server') $SQLname

# -
# - To change from Windows Trusted Connection and use SQL Server Security.
# -
$MySQL.ConnectionContext.LoginSecure = $false
$MySQL.ConnectionContext.set_Login('SQLUserID')
$SqlUPwd = ConvertTo-SecureString 'SQLPassword' -AsPlainText -Force
$MySQL.ConnectionContext.set_SecurePassword($SqlUpwd)

So, as you can see, the first two lines didn’t change. This is because the first two lines may expect to use Windows authentication but the following lines are the ones that change the security context to use SQL Authentication.  if there’s no errors then you can start querying your SQL engine for information.

That’s it!

Posted in Uncategorized | Leave a comment

Deploying SSIS Packages using DTUtil.exe with PowerShell – Part 3…

Here’s the final blog – Part 3 of this series.

Now, we have taken one of the previously build Deploy SSIS function (“ Deploy-File2SQL ”), included in a compiled Windows application, and then integrate this solution to be run from within Visual Studio 2008.  For this solution I need to have the following:

1. I’m using SAPIEN Technologies “Primal Forms 2009” (the full edition) which allow me to compile my script creating my executable.

2. Add two of my previously created function: 1. “Show-MsgBox” and 2.“Deploy-File2SQL.ps1“.  Then, make some modifications to the code so it can use in this Windows Application.

3. Finally, have my Visual Studio 2008 ready so I can add my solution under the “Tool” pull-down menu.

Here’s how my DeploySSIS Windows Application look like in Primal Form 2009:

Here’s running the application:

The good thing about Primal Forms 2009, is that it will generate the code for the Windows form and you only need to fill the code behind.  The best feature I consider valuable is that you can create an Windows executable.

This is just to show you how you can improve your PowerShell scripting to the point of building a practical executable solution that can be easily deploy to a Microsoft application.

Now, let see the integration to Visual Studio 2008.  We are going to add our solution under the “Tool” drop-down menu.  But, in order to do this we need to, under “Tools”, click on “External Tools…”,  then click on the “Add” button, and fill out the information:

Now, when you go back to Visual Studio 2008 and click on the Tool menu, we can see our added item.  So, when you completed building your SSIS package solution in Visual Studio and ready to deploy to a server, then you can do this from within your development environment. 

This is how it looks:

1. Look for the “Deploy File to SQL”, click to execute

2. Look for the SSIS package to be deploy to SQL Server 2008 Integration Services and the rest of the information will be auto-filled.

3. Before we execute to deploy this package we can do the following:

a. By Default, the “SQL Server Destination” is your local machine, but you can change this to another server.

b. The “Copy To…” field you can rename your SSIS package.

4. Now, we are ready to click on “Execute/Deploy” button to copy our SSIS package to SQL Integration Services:

Our solution works and it will run DTUtil from our “Deploy-File2SQL” function and now you can deploy SSIS packages from your file system to your SSIS SQL Server. 

If you would like a copy of this solution, I will have it available from CodePlex Project PSMaxTinyTools or send me an email to maxt@putittogether.net

Happy PowerShelling!!

Posted in PowerShell | Leave a comment

Deploying SSIS Packages using DTUtil.exe with PowerShell – Part 2…

In Part 1, I created both a batch file and a PowerShell script that would allow me to pass parameters to the SQL Server dtutil.exe command use to manage SQL Server Integration Services packages. This example is meant to show how to work with parameters and pass values to a command Batch file. And, I know, we are using two files that need to be in the same folder in order to run without any problems.

Now, in Part 2, this script has evolved from a script file to a three separate functions. We got rid of the batch file.  I’m going to auto0generatge the batch file from the within the functions and then execute the batch file. This batch file will be create in the “C:\Users\YourName\Documents\WindowsPowerShell” folder and it will be overwritten every time a function is executed.  Each function has a help documentation using the cmdlet: Get-help or help FunctionName –full

But, what was learned in part two:

1. Evolving from a PowerShell script to an advance function with required parameters

2. Build a string variable with your batch command lines with area you can replace string values.

3. Add the help comments in the functions.

 

Here’s the three new functions for the copying SSIS packages: (below is the full source code)

1. Deploy-SQL2DTS

2. Deploy-File2SQL

3. Deploy-File2File

Requirements for these functions:

1. You need to have your PowerShell User profile folder in place.

2. You can three functions in your Microsoft.PowerShell_profile.ps1 script file for quick execution.

3. If you don’t want to load all functions to the profile then use the Dot-Source way to load the function separately:

example:  PS> . .\Deploy-SQL2DTS.sp1

4. In cases the “Program files” folder reside on a different drive letter, then change the directory path in the batch file string inside all three functions.

5. The auto-generated batch file will be created in your Users WindowsPowerShell folder.  But, if you want to change this, look for the variable name $DefaultBatchBuildLocation to change the location to store the batch file.

Here’s all three functions code:

1. Deploy-SQL2DTS.ps1 – Copy SQL MSDB package to another folder under MSDB folder.

 
# ==============================================================================================
# Microsoft PowerShell Source File -- Created with SAPIEN Technologies PrimalScript 2009
# NAME: Deploy-SQL2DTS.ps1
# AUTHOR: Max Trinidad,
# DATE : 4/24/2010
#
# COMMENT: This is function will copy a SQL package to another folder in SQL Integration Services msdb.
#
# ==============================================================================================

function Deploy-SQL2DTS {
<#
.SYNOPSIS
Deploy SSIS package, using the "/Copy" switch, to a SQL Server Integration Services store.
.Description
This function will allow you to deploy a copy SSIS package in SQL MSDB to another folder in MSDB SQL Server Integration Services.
All the parameters are require to deploy the package (except for "is2k8"). This function can be use in both PowerShell V1 and V2. Has the alias dsd
.Parameter is2K8
is2K8 - [String]. This is to identify is the package is going to a SQL Server 2008 Integration Services store. (Required)
Enter a "y" for SQL2k8 and "n" for SQL2k5.
.Parameter SrcFile
SrcFile - [String]. This is your SSIS package store in MSDB. (Required)
.Parameter CopyTo
CopyTo - [String]. This is the SQL Server destination name include in MSDB\foldername. (Required)
.Example
PS> Deploy-SQL2DTS Y Sample_SSISpkg01 MSDB\BACKUPSSIS\Sample_SSISpkg01
Using the full function name with all parameters
.Example
PS> dsd Y Sample_SSISpkg01 MSDB\BACKUPSSIS\Sample_SSISpkg01
Using the alias function with all parameters
.Example
PS> dsd c:\temp\Sample_SSISpkg01.dtsx Sample_SSISpkg01_copy
Using the full function name but excluding the first parameters because will deploy to SQL Server 2005 Integration Services
.Notes
NAME: Deploy-SQL2DTS
Alias: dsd
AUTHOR: Max Trinidad
Created: 04/16/2010 21:16:01 - Version 0.1
Compatibility - Version 1 and Version 2
.Link
about_functions
about_functions_advanced
about_functions_advanced_methods
about_functions_advanced_parameters
.Inputs
is2K8 - [String] - Required
SrcFile - [String] - Required
CopyTo - [String] - Required
#>
Param(
[Parameter(Mandatory=$true, Position=0)] [string] $is2K8,
[Parameter(Mandatory=$true, Position=1)] [string] $SrcFile,
[Parameter(Mandatory=$true, Position=2)] [string] $CopyTo
)

#Initializing variables
$SQLver = "999"
$SQLVName = "SQLServerDesc"

#Location where the create batch file will be build.
$DefaultBatchBuildLocation = $Env:UserProfile + "\My Documents\WindowsPowerShell"

#This is the string use to create the batch file.
$Batch = @"
@echo SQLServerDesc
@echo Running SSIS Deploy PckgUtil batch process
@echo ------------------------------------------
@echo Param1 = %1
@echo Param2 = %2
@echo ------------------------------------------
@echo -
C:\"Program Files"
\"Microsoft SQL Server"\999\DTS\Binn\dtutil.exe /Quiet /SQL %1 /copy DTS;%2
@Echo Process completed!
"@

#Write-Host $is2K8 $SrcFile $CopyTo

if ($is2K8.ToString() -eq "
Y"){

# Run DTUtil.exe from the SQL 2008 path - Running DOS batch command
$SQLver = "
100"; $SQLVName = "SQL Server 2008"
Write-Host "
Building SQL2k8 Deploy Batch file in $DefaultBatchBuildLocation"

# Display the datetime before execution
Get-Date

#Building batch file step
$Batch = $Batch.replace("
SQLServerDesc",$SQLVName)
$Batch = $Batch.replace("
999",$SQLver)
$Batch | Out-File -FilePath $DefaultBatchBuildLocation\Deploy-SSISPkgUtil.bat -Encoding ASCII

#Execute created batchfile
& $DefaultBatchBuildLocation\Deploy-SSISPkgUtil.bat $SrcFile $CopyTo

# Display the datetime after execution
Get-Date

} else {
# Run DTUtil.exe from the SQL 2005 path - Running DOS batch command
$SQLVer = "
90"; $SQLVName = "SQL Server 2005"
Write-Host "
Building SQL2k5 Deploy Batch file in $DefaultBatchBuildLocation"

# Display the datetime before execution
Get-Date

#Building batch file step
$Batch = $Batch.replace("
SQLServerDesc",$SQLVName)
$Batch = $Batch.replace("
999",$SQLver)
$Batch | Out-File -FilePath $DefaultBatchBuildLocation\Deploy-SSISPkgUtil.bat -Encoding ASCII

#Execute created batchfile
& $DefaultBatchBuildLocation\Deploy-SSISPkgUtil.bat $SrcFile $CopyTo

# Display the datetime after execution
Get-Date
}

}; Set-Alias dsd Deploy-SQL2DTS

2. Deploy-File2SQL.ps1 – Copy a SSIS package store in the filesystem to SQL MSDB folder.  Reminder, you can’t deploy an SSIS 2K8 package to a SQL Server 2K5 Integration Services or you get the below message “Could not load package…”.

SQL Server 2008 Integration Services

 SQL Server 2005 Integration Services

  
# ==============================================================================================
# Microsoft PowerShell Source File -- Created with SAPIEN Technologies PrimalScript 2009
# NAME: Deploy-File2SQL.ps1
# AUTHOR: Max Trinidad,
# DATE : 4/24/2010
#
# COMMENT: Deploy SSIS package, using the /File to copy the SSIS package from the filesystem to SQL Server Integration Services MSDB.
# to SQL Server Integration Services MSDB.
# ==============================================================================================

function Deploy-File2SQL {
<#
.SYNOPSIS
Deploy SSIS package, using the /File to copy the SSIS package from the filesystem to SQL Server Integration Services MSDB.
.Description
This function will allow you to deploy SSIS package *.dtsx to a SQL Server Integration Services. All the parameters are
require to deploy the package (except for "is2k8"). This function can be use in both PowerShell V1 and V2. Has the alias dfs
.Parameter is2K8
is2K8 - [String]. This is to identify is the package is going to a SQL Server 2008 Integration Services store. (Required)
Enter a "y" for SQL2k8 and "n" for SQL2k5.
.Parameter SrcFile
SrcFile - [String]. This is your SSIS package fullpath and name . (Required)
.Parameter CopyTo
CopyTo - [String]. This is the SQL Server destination name. (Required)
.Example
PS> dfs Y c:\temp\Sample_SSISpkg01.dtsx MAX-PCWIN1 Sample_SSISpkg01_copy
Using the full function name with all parameters
.Example
PS> Deploy-CopySSIS Y c:\temp\Sample_SSISpkg01.dtsx MAX-PCWIN1 Sample_SSISpkg01_copy
Using the alias function with all parameters
.Example
PS> dfs c:\temp\Sample_SSISpkg01.dtsx MAX-PCWIN1 Sample_SSISpkg01_copy
Using the full function name but excluding the first parameters because will deploy to SQL Server 2005 Integration Services
.Notes
NAME: Deploy-File2SQL
Alias: dcs
AUTHOR: Max Trinidad
Created: 04/25/2010 21:16:01 - Version 0.1
Compatibility - Version 1 and Version 2
.Link
about_functions
about_functions_advanced
about_functions_advanced_methods
about_functions_advanced_parameters
.Inputs
is2K8 - [String] - Required
SrcFile - [String] - Required
DestSrv - [String] - Required
CopyTo - [String] - Required
#>

Param(
[Parameter(Mandatory=$true, Position=0)] [string] $is2K8,
[Parameter(Mandatory=$true, Position=1)] [string] $SrcFile,
[Parameter(Mandatory=$true, Position=2)] [string] $DestSrv,
[Parameter(Mandatory=$true, Position=3)] [string] $CopyTo
)

#Initializing variables
$SQLver = "999"
$SQLVName = "SQLServerDesc"

#Location where the create batch file will be build.
$DefaultBatchBuildLocation = $Env:UserProfile + "\My Documents\WindowsPowerShell"

#This is the string use to create the batch file.
$Batch = @"
@echo SQLServeraDesc
@echo Running SSIS_Deploy_PckgUtil batch process
@echo ------------------------------------------
@echo Param1 = %1
@echo Param2 = %2
@echo Param3 = %3
@echo ------------------------------------------
@echo -
C:\"Program Files"
\"Microsoft SQL Server"\999\DTS\Binn\dtutil.exe /Quiet /FILE %1 /DestServer %2 /copy SQL;%3
@Echo Process completed!
"@

#Write-Host $is2K8 $SrcFile $DestSrv $CopyTo

if ($is2K8.ToString() -eq "
Y"){

# Run DTUtil.exe from the SQL 2008 path - Running DOS batch command
$SQLVer = "
100"; $SQLVName = "SQL Server 2008"
Write-Host "
Building SQL2k8 Deploy Batch file in $DefaultBatchBuildLocation"

# Display the datetime before execution
Get-Date

#Building batch file step
$Batch = $Batch.replace("
SQLServerDesc",$SQLVName)
$Batch = $Batch.replace("
999",$SQLver)
$Batch | Out-File -FilePath $DefaultBatchBuildLocation\Deploy-SSISPkgUtil.bat -Encoding ASCII

#Execute created batchfile
& $DefaultBatchBuildLocation\Deploy-SSISPkgUtil.bat $SrcFile $DestSrv $CopyTo

# Display the datetime after execution
Get-Date

} else {
# Run DTUtil.exe from the SQL 2005 path - Running DOS batch command
$SQLVer = "
90"; $SQLVName = "SQL Server 2005"
Write-Host "
Building SQL2k5 Deploy Batch file in $DefaultBatchBuildLocation"

# Display the datetime before execution
Get-Date

#Building batch file step
$Batch = $Batch.replace("
SQLServerDesc",$SQLVName)
$Batch = $Batch.replace("
999",$SQLver)
$Batch | Out-File -FilePath $DefaultBatchBuildLocation\Deploy-SSISPkgUtil.bat -Encoding ASCII

#Execute created batchfile
& $DefaultBatchBuildLocation\Deploy-SSISPkgUtil.bat $SrcFile $DestSrv $CopyTo
# Display the datetime after execution
Get-Date
}

}; Set-Alias dfs Deploy-File2SQL

3. Deploy-File2File.ps1 – Copy the SSIS package stored in the filesystem to another location in the *filesystem or the same location but different package name.
 
*Note: As you can see in this picture, make sure to include the *.dtsx extension.

# ==============================================================================================
# Microsoft PowerShell Source File -- Created with SAPIEN Technologies PrimalScript 2009
# NAME: Deploy-File2File.ps1
# AUTHOR: Max Trinidad,
# DATE : 4/26/2010
#
# COMMENT: This is function will deploy a copy of a SSIS package in the filesystem to another
# filesystem folder.
# ==============================================================================================

function Deploy-File2File {
<#
.SYNOPSIS
Deploy a copy of a SSIS package in the filesystem to another filesystem folder.
.Description
This function will allow you to deploy SSIS package *.dtsx to another filesystem folder. All the parameters are
require to deploy the package(except for "is2k8"). This function can be use in both PowerShell V1 and V2. Has the alias dff
.Parameter is2K8
is2K8 - [String]. This is to identify is the package is going to a SQL Server 2008 Integration Services store. (Required)
Enter a "y" for SQL2k8 and "n" for SQL2k5.
.Parameter ScrFile
ScrFile - [String]. This is your SSIS package fullpath and name . (Required)
.Parameter CopyTo
CopyTo - [String]. This is the SQL Server destination name. (Required)
.Example
PS> dff Y c:\temp\Sample_SSISpkg01.dtsx C:\Temp\Sample_SSISpkg01_copy.dtsx
Using the full function name with all parameters
.Example
PS> Deploy-File2File Y c:\temp\Sample_SSISpkg01.dtsx C:\Temp\Sample_SSISpkg01_copy.dtsx
Using the alias function with all parameters
.Example
PS> dff C:\temp\Sample_SSISpkg01.dtsx C:\Temp\Sample_SSISpkg01_copy.dtsx
Using the full function name but excluding the first parameters because will deploy to SQL Server 2005 Integration Services
.Notes
NAME: Deploy-File2File
Alias: dcs
AUTHOR: Max Trinidad
Created: 04/25/2010 21:16:01 - Version 0.1
Compatibility - Version 1 and Version 2
.Link
about_functions
about_functions_advanced
about_functions_advanced_methods
about_functions_advanced_parameters
.Inputs
is2K8 - [String] - Required
SrcFile - [String] - Required
DestSrv - [String] - Required
CopyTo - [String] - Required
#>

Param(
[Parameter(Mandatory=$true, Position=0)] [string] $is2K8,
[Parameter(Mandatory=$true, Position=1)] [string] $SrcFile,
[Parameter(Mandatory=$true, Position=3)] [string] $CopyTo
)

#Initializing variables
$SQLver = "999"
$SQLVName = "SQLServerDesc"

#Location where the create batch file will be build.
$DefaultBatchBuildLocation = $Env:UserProfile + "\My Documents\WindowsPowerShell"

#This is the string use to create the batch file.
$Batch = @"
@echo SQLServeraDesc
@echo Running SSIS_Deploy_PckgUtil batch process
@echo ------------------------------------------
@echo Param1 = %1
@echo Param2 = %2
@echo ------------------------------------------
@echo -
C:\"Program Files"
\"Microsoft SQL Server"\999\DTS\Binn\dtutil.exe /Quiet /FILE %1 /copy File;%2
@Echo Process completed!
"@

#Write-Host $is2K8 $SrcFile $DestSrv $CopyTo

if ($is2K8.ToString() -eq "
Y"){

# Run DTUtil.exe from the SQL 2008 path - Running DOS batch command
$SQLVer = "
100"; $SQLVName = "SQL Server 2008"
Write-Host "
Building SQL2k8 Deploy Batch file in $DefaultBatchBuildLocation"

# Display the datetime before execution
Get-Date

#Building batch file step
$Batch = $Batch.replace("
SQLServerDesc",$SQLVName)
$Batch = $Batch.replace("
999",$SQLver)
$Batch | Out-File -FilePath $DefaultBatchBuildLocation\Deploy-SSISPkgUtil.bat -Encoding ASCII

#Execute created batchfile
& $DefaultBatchBuildLocation\Deploy-SSISPkgUtil.bat $SrcFile $CopyTo

# Display the datetime after execution
Get-Date

} else {
# Run DTUtil.exe from the SQL 2005 path - Running DOS batch command
$SQLVer = "
90"; $SQLVName = "SQL Server 2005"
Write-Host "
Building SQL2k5 Deploy Batch file in $DefaultBatchBuildLocation"

# Display the datetime before execution
Get-Date

#Building batch file step
$Batch = $Batch.replace("
SQLServerDesc",$SQLVName)
$Batch = $Batch.replace("
999",$SQLver)
$Batch | Out-File -FilePath $DefaultBatchBuildLocation\Deploy-SSISPkgUtil.bat -Encoding ASCII

#Execute created batchfile
& $DefaultBatchBuildLocation\Deploy-SSISPkgUtil.bat $SrcFile $CopyTo
# Display the datetime after execution
Get-Date
}

}; Set-Alias dff Deploy-File2File

Now, feel free to copy/paste this three functions.  And, as you probably notice, there’s still room for improvements.
 
For next week, Part 3 – Integrating your solution into your Visual Studio application.
 

Happy PowerShelling!!!

Posted in Uncategorized | 5 Comments