In my previousarticle, I showed you how to use PowerShell to create a script to dump out all the tables of your databases to files. One concept that was introduced at the time was that PowerShell treats everything as an object. In this article, you’ll get a chance to take a closer look at this.
Open the PowerShell ISE and execute the following commands
dir C:\Image may be NSFW.
Clik here to view.

The results are about what you’d expect. Your output, of course, will vary a bit. The format is a little different from what you’d see in the CMD processor (it’s closer to a Unix style directory listing), but it’s recognizable as a directory listing.
Now try:
#this assumes you have a default instance on your local system, if you don't, change the word default to the name of your instance or change the server name $sqlserver = 'localhost\default' invoke-sqlcmd cd sqlserver:\sql\$sqlserver dir databasesNow you’ll get back something very different from a filesystem listing, but it should be something that should be somewhat recognizable, a list of databases.
Image may be NSFW.
Clik here to view.

Back up a step and discover what else you can see. Enter the following command:
get-psdriveImage may be NSFW.
Clik here to view.

This output shows all the current locations that PowerShell can treat as a drive tree. Since this was run on a server as administrator, I could drill down and look at the Active Directory information. You probably will not see this on your machine. You will also see other objects that are specific to your machine. You can’t usually see SQLServer, but using the Invoke-SQLCmd forces the loading of the code necessary to make that happen. To access any of these objects, just type cd <objectname> .
I used the cmdlet Invoke-SQLCmd earlier in the article. What that did, however, was merely to force the loading of a PowerShell library. You can load the library directly with the following command when it’s not already loaded.
import-module sqlpsYou may get a warning message, about some verbs being unapproved . This warning doesn’t impact your ability to use them. You can ignore the warning message. If you’re curious about what cmdlets are being imported, try viewing both approved and unapproved by running the following command.
import-module sqlps -verboseIf, for some reason, you want to remove all the SQL related cmdlets, use
Remove-Module sqlpsI can’t think of a reason to do that, other than perhaps to free up memory.
PowerShell treats the objects in SQL Server like it treats files in a directory. By running dir databases , you get a list of your user databases. The system databases are not listed, but, you can treat them like hidden files and use the force parameter.
ls databases -forceImage may be NSFW.
Clik here to view.

I changed commands slightly here and used ls instead of dir . Dir is an alias for ls , which in turn is an alias for get-childitem . PowerShell uses a lot of aliases that map to cmdlets of the verb-noun form. Since it’s shorter and the syntax is closer to the Unix form, I will use ls from now on.
Just like in a windows or Unix filesystem, you can navigate further. Run this to see the objects listed under the SQLServer directory.
ls .Image may be NSFW.
Clik here to view.

You should recognize these as objects and collections of objects that are found on SQL Server, for example, LinkedServers and Logins. You can explore any of those areas. To see the logins that exist on this server, run:
ls logins -forceImage may be NSFW.
Clik here to view.

Notice that I used the force parameter. Without that, some of the above logins, like sa , would not show up.
Looking at ObjectsSo far, the examples explore SQL Server like a filesystem. But again, PowerShell is about the objects.
$logins = ls logins -force $loginsThis will show you all the logins in the system after the collection has been saved in a variable. This command is useful, but what if you want just a list of the sqllogins ?
ls logins -force | where {$_.logintype eq 'sqllogin'}Image may be NSFW.
Clik here to view.

This takes the results of the ls logins command and pipes it to the where command. You have to tell where what to act on. $_ is a shorthand for referencing the most recently used object; in this case the output of the ls logins force command. PowerShell uses -eq (and gt and -lt and ne ) to test for equality. This command will show you all logins on the server that are of the type sqllogin . It does this by looking at the logins property of logintyp e.
This can also be done by using two commands, saving the collection in a variable first so that it can be reused:
$logins = ls logins -force $logins | where {$_.logintype eq 'sqllogin'}Every object has properties, some more than others. To see what properties and methods an object may have, pipe it to the get-member cmdlet.
$logins | get-member | out-gridviewOr if you want to be very frugal in your typing, you can use aliases:
$logins | gm | ogvBy piping the output to out-gridview , you can take advantage of the GUI and have an easy to read window that allows you to filter further.
Image may be NSFW.
Clik here to view.

And with a filter applied:
Image may be NSFW.
Clik here to view.

This is showing you all the login properties related to passwords.
Viewing Properties in Multiple ServersImagine the auditor has come to you and wants to know which logins exist on the SQL Server instance, which ones are enabled, and which ones have password expiration enabled. You could do this as a T-SQL query, but you need to execute this against 100 different servers.
Start with:
$logins | select-object name,ispasswordexpired, MustChangePassword, isdisabled, passwordexpirationenabledYou most likely will get results like this:
Image may be NSFW.
Clik here to view.

The select-object command permits selecting which properties you want from the logins object. However, you may want it in a more readable format. This is where the format-table cmdlet that was mentioned in the last article can be useful.
ls logins -force| select-object name,ispasswordexpired, MustChangePassword, isdisabled, passwordexpirationenabled | format-tableImage may be NSFW.
Clik here to view.

You now have the results for one server, but you have 99 more to go. You can take advantage of the looping from the last article and the fact that you can use an array of strings:
#Update the array to reflect your instances $sqlservers = @('SQL01\default','SQLDB_02\sqlexpress','SalesSQL\default', 'SalesSQL\TEST_Instance') foreach ($sqlserver in $sqlservers) { cd sqlserver:\sql\$sqlserver ls lo