Accessing a PowerShell Class Defined In A Module From Outside A Module

PowerShell 5 introduced the concept of classes. This is an exciting new feature that will really help promote code reusability. It seems natural then, that you would want to organize your classes into PowerShell Modules.

It’s not obvious though, how to use a class defined inside a module from outside that module. There are, in fact, three methods available to you.

Let’s say you have a module, MyModule.psm1. In it you’ve defined a class:

class MyClass
{
  [string] $MyString = 'My String Value'

  [string] GetSomeValue()
  {
    return 'Some Value'
  } 

}

Simple enough. So how do we get to this masterpiece of class coding? The first technique has us creating a function inside the module. Within that function we return a new instance of the class.

function Get-NewMyClass()
{
  return [MyClass]::new()
}

# Export the function, which can generate a new instance of the class
Export-ModuleMember -Function Get-NewMyClass

Using it simply requires we import the module, then call the function. From there we can access the properties and methods of our function.

# Import our test module
Import-Module -Force 'C:\PS\Classes and Modules\mymodule.psm1'

# Use the function to generate a new instance of the 'MyClass' class
$myClassFunction = Get-NewMyClass

# Call a method from it
$myClassFunction.GetSomeValue()

# Get a property of the class
"MyString=$($myClassFunction.MyString)"

Pretty simple and straightforward. This can be a useful method if there are extra checks you wish to do inside the module prior to returning the new instance of the class.

The next method simply has us create a variable within the module, and export that as a module member.

$newClass = [MyClass]::new()
Export-ModuleMember -Variable newClass

You’d then use it in your script, just like any other variable:

# The module also has a variable exported from the function
# of type MyClass. 
"NewClass=$($newClass.MyString)"
$newClass.GetSomeValue()

With that shown I have to say I really don’t like this method. Primarily it is due to the issue of name collisions. If you have a variable also named $newClass in your script, it will block out the one from the class causing the collison.

The final option is the new using clause. I want to give a shout out to PowerShell MVP Dave Wyatt (blog | twitter) for pointing this one out to me.

As the first line of your script (except for comments, which are allowed before it) you use the syntax “using module” followed the module name, or path to the module.

using module 'C:\PS\Classes and Modules\mymodule.psm1'

Here I hard coded the path to the module since this is a simple demo. If the module had been installed in one of the default locations for modules, such as the WindowsPowerShell\Modules folder in the current users Documents area, you could have omitted the path and just put the name of the module.

After this, you would simply create a new variable from the class and use it normally.

$myClassUsing = [MyClass]::new()

# Setting / Getting property
$myClassUsing.MyString                  # Show default property
$myClassUsing.MyString = 'ArcaneCode'   # Change the value
$myClassUsing.MyString                  # Show the change

# Calling a method
$myClassUsing.GetSomeValue()

Note that if you had multiple modules you wanted to access the class definitions in, you would simply have multiple lines of “using module”, each line referencing the module you wanted.

using module 'C:\PS\Classes and Modules\mymodule.psm1'
using module 'C:\PS\Classes and Modules\anothermodule.psm1'

 

There you go. Three ways you can access a class definition stored inside a module, externally. Now not only can you create useful, reusable classes, you can also organize them into modules and use them outside the modules.

High Class PowerShell–Presenting for the SQL PASS PowerShell Virtual Chapter

I’m pleased to announce I’ll be presenting for the SQL PASS PowerShell Virtual Chapter this Wednesday April 6th, 2016, at 12 pm Eastern Time (GMT-5).

In this session I’ll focus on the ability to create custom objects in PowerShell, covering PowerShell versions 3 to 5. I’ll then dive into the use of the new Class and Enum types introduced in PowerShell 5.

To join me, simply go to https://attendee.gotowebinar.com/register/2277748661677465857 and register. It’s free, fast and easy. If you can’t make it live, don’t worry these sessions are recorded and will be posted for viewing later.

Hope to see everyone there!

Getting Music on your Windows Phone with Windows Media Player

I admit it. I have a Windows Phone. And I like it.

I’ve had an iPod, which is more than enough to tell me I don’t want an iPhone. Every time I switched PCs it was like starting over with a brand new device. Egad.

I also had an Android phone. It did a terrible job of letting me organize my apps, and often rearranged them after an update, leaving me once again to try and find where the heck everything is.

No, I like the simplicity of my Windows Phone. Easy to use, easy to setup. True, as critics say there’s not a lot of apps. But an awful lot of what I need I can do just via the web. Starbucks is a great example, they have an excellent mobile website through which I can check my card balance, see my current points (stars), and easily refill my card.

Truth be told, I actually have two Windows Phones. One is my large Samsung ATIV-SE, which I use daily. I also have a small inexpensive Nokia, only has 4 gig of ram but takes a 128 gig SD card. (The SD card cost twice as much as the phone.) When I travel I don’t want to run down the battery on my Samsung phone, so it works as a great device for playing my music, podcasts, and Audible audiobooks. Additionally, f something ever happened to the Samsung I can run and get a cheap SIM card and use it for a backup. I’ve nick named it ‘Zune’.

The one painful thing is getting music on my phones. One option is to simply open up File Explorer and copy things across. But that doesn’t let you really manage it well, and doesn’t help with playlists.

Another option is the Windows Phone desktop app. What a big pile of steaming poo that is. There’s a Windows 8 style app for it, which isn’t any better but is prettier. Of course there’s Groove / XBox Music. It does a great job of organizing music and playlists. But wait, it doesn’t talk to the Windows Phone. WTF Microsoft??? Come on, three different apps, none of which are worth a flip with the Windows Phone.

I’ve found the best app to be good old Windows Media Player. Yes, you heard me, the ancient but venerable Windows Media Player. It is easy to organize music and other types of media, as well as create playlists. Even better, when I plug in my phones it just recognizes them and shows up in the Sync tab. All I have to do is drag playlists or other media to it and click the start sync, and away it goes.

Unfortunately it’s a one way sync, it won’t retrieve things from the phone, but I can live with that.

I did have one frustrating moment last night. I was creating some new playlists, then when I went to sync them something happened. Not sure what, but everything went kablooie. Sync failed, and when I looked back many of my playlists had vanished.

I uttered a long string of explicatives involving the fleas of a thousand llamas and the armpits of most Microsoft Executives, then sighed and went to recreate one of them. When I did, it told me the list already existed! I went to look and of course didn’t see it, but I still had some glimmer of hope my lists were still there, like gold nuggets waiting to be found.

I put my Bingfu skills to work, and quickly found this question/answer in the Microsoft forums:

http://answers.microsoft.com/en-us/windows/forum/windows_7-pictures/missing-playlists-in-windows-media-player-12-for/176a2d8f-568a-4bce-8488-b6c640c2859b?auth=1

The solution came from one Afzal Taher, who appears to be a Microsoft employee. Or at least he was as of 2010 when the answer was posted.

His answer had multiple options you could try, but the first was all I needed. (If the below doesn’t work for you reference the above link).

1. Exit Windows Media Player.

2. Hold down the Windows Key and press R (for Run). Type %LOCALAPPDATA%\Microsoft\Media Player and click OK.

3. Select all the files in that folder, and delete them. NOTE! DO NOT DELETE THE FOLDERS! Only the files.

4. Restart Windows Media Player.

Of course any time you delete files, do it with caution, and you’re on your own, no warranties from me.

When you restart Windows Media Player, it will begin rebuilding its database. I have literally hundreds of gigs of music. My collection has records and/or CDs back to the late 70’s that I’ve digitized because I’m really old and we all know the last decade for original music was the 80’s. Except for ZZ Top. No matter when their stuff comes out, it rocks. (Also a shout-out to DJ Lobsterdust for his really innovative mash-ups.)

Anyway, this was an overnight process for me. But this morning, all my songs and playlists were back, even the ones that had vanished. I was able to sync my playlists to my phones with no problem, and am now happily rocking out while writing some PowerShell code.

Hmmm. PowerShell + Windows Phone + Windows Media Player. I wonder….

Encoding Strings to Base64 in C# – The Movie

Way back in 2007 I wrote a blog post entitled “Encoding Strings to Base64 in C#”. This continues to be my #1 referenced post.

The guys over at Webucator have turned my post into an instructional video, and I couldn’t be happier with the results. You can find the video on YouTube at:

https://www.youtube.com/watch?v=r94gKb-NzLM&feature=youtu.be

Make sure to give ‘em a like for all their hard work!

Easy Installation of Your Own PowerShell Modules

I’ve been working a lot with PowerShell of late, developing modules and deploying them to my own Modules folder. This is a pretty basic set of tasks, something I do over and over. As such, I decided to script it!

First thing I wanted to do was ensure the WindowsPowerShell\Modules folder exists under the users Documents folder. To do that I created a simple function, Add-WindowsPowerShellFolder. If the WindowsPowerShell folder, and under it the Modules folder, don’t exist, they are created.

#—————————————————————————–#
# This checks to see if the WindowsPowerShell folder is in the users
# document folder, then checks to see if the Modules folder exists under
# the WindowsPowerShell folder. If they do not exist, they are created.
# This is primarily a helper function for the Install-MyModule function
#—————————————————————————–#
function Add-WindowsPowerShellFolder()
{
 
  $psUserPath = "C:\Users\$([Environment]::UserName)\Documents\WindowsPowerShell"
  if($(Test-Path $psUserPath) -eq $false)
  {
    New-Item -ItemType Directory -Force $psUserPath
  }

  $psUserModulePath = "$($psUserPath)\Modules"
  if($(Test-Path $psUserModulePath) -eq $false)
  {
    New-Item -ItemType Directory -Force $psUserModulePath
  }

}

Next, I check to see if the folder for the specific Module I’m wishing to deploy exists, and if not create it.

#—————————————————————————–#
# This checks to see if the folder for the Module you want to install
# exists, and if not it adds it.
# This is primarily a helper function for the Install-MyModule function
#—————————————————————————–#
function Add-ModuleFolder($ModuleName)
{
 
  $psUserModulePath = "C:\Users\$([Environment]::UserName)\Documents\WindowsPowerShell\Modules"

  $psModulePath = "$($psUserModulePath)\$($moduleName)"
  if($(Test-Path $psModulePath) -eq $false)
  {
    New-Item -ItemType Directory -Force $psModulePath
  }

}

Finally I call the main function, the Install-MyModule. This has two parameters, the name of the Module and a collection of files to copy.

First, I use the functions above to validate the needed folders exist. There is also a switch, –Replace, which will delete all files and subfolders in the target module folder.

After this is a simple routine that loops over each file and copies it to the target. This allows you to copy files from multiple folders all to the same target.

This routine does assume there are no subfolders to be deployed to the target module folder, which is pretty common.

 

#—————————————————————————–#
# This is the main function of this script. It first ensures the requisite
# folders exist in order to deploy.
#
# If the -Replace switch is used, the target folder will be cleaned out
# prior to the copy.
#
# Next, it iterates over the list of files passed in and copies them to the
# target folder.
#—————————————————————————–#
function Install-MyModule()
{
  [CmdletBinding()]  
  param ( 
         [Parameter( Mandatory = $true,
                     ValueFromPipeline = $false,
                     ValueFromPipelineByPropertyName = $false,
                     HelpMessage = ‘Module Name.’
                     )]
         [string] $ModuleName,
         [Parameter( Mandatory = $true,
                     ValueFromPipeline = $false,
                     ValueFromPipelineByPropertyName = $false,
                     HelpMessage = ‘File to deploy.’
                     )]
         [string[]] $Files,
         [switch] $Replace
        )  # End the parameter block

  begin
  {
    # Validate the PS folder exists
    Add-WindowsPowerShellFolder

    # Set the path to the users modules folder
    $psUserModulePath = "C:\Users\$([Environment]::UserName)\Documents\WindowsPowerShell\Modules"

    # Add a new folder for the module name being installed
    Add-ModuleFolder -ModuleName $ModuleName

    # Set the path to the users module folder including the module to create
    $psModulePath = "$($psUserModulePath)\$($ModuleName)"

    # If the user passed the -Replace switch delete all files from
    # the target folder
    if ($Replace -eq $true)
    {
      Remove-Item "$psModulePath\*.*" -Force -Recurse
    }

  }
 
  process
  {

    foreach($file in $files)
    {
      # Copy our module to the users module folder (force will overwrite if there)
      Copy-Item $file `
                $psModulePath `
                -Force
    }
  }
 
}

Using it is straight forward. First, place the above code into a PS1, then execute it to load the functions into memory. You could also put it in your profile if it is something you do often.

In this example I’ve developed a module called ZipCodeLookup. This example installs it for me into my modules folder.

Install-MyModule ‘ZipCodeLookup’ ‘C:\PS\MyCode\ZipCodeLookup.*’ –Replace

Now you have a simple function you can call to deploy your modules, making your development life a little easier. It can also come in useful when sending a module to a coworker or setting up some common scripts on a different machine. It takes care of making sure the folders are in place as well as copying in your module.

Chattanooga SQL Saturday June 27 2015–Zero to Hero with PowerShell and SQL Server

This Saturday, June 27 2015, I will be at SQL Saturday #410 in Chattanooga, TN. I’ll be presenting a session “Zero to Hero with PowerShell and SQL Server”, in which we’ll start with the basics of PowerShell, then move into working with SQL Server via the PS SQL Provider.

This is going to be an extremely fast paced session, so you may wish to download the code samples ahead of time. I have already uploaded the samples to the event site. Just go to the Sessions menu, Schedule, and you’ll see a bit download button under the session. As of right now I’m the last session of the day, in room 219, but that is subject to change so be sure to check the schedule upon arrival.

Be warned, there is far more code in the download then we’ll be able to cover in a one hour session. It is well commented though, and you should be able to understand it after the session.

If you are looking for even more PowerShell goodness, my friend Aaron Nelson ( @sqlvariant | blog ) is doing a PowerShell for Data Professionals just after lunch. Our two sessions should work well together for those interested in using PowerShell in the world of SQL Server.

Hope to see you there!

SSRS 2012 Report Manager can’t load Microsoft.ReportingServices.SharePoint.ObjectModel

So I did it again, I broke my SQL Server. Well, sort of. I have a Hyper-V VM of Windows Server 2012R2 I use for development. On it I had SQL Server 2012 Developer Edition with all the latest service packs. I recently needed to do some work with 2014 as well, so installed SQL Server 2014 Developer Edition side by side. Everything seemed happy, until I opened up the SQL Server 2012 Report Manager webpage. It looked OK at first, but when I started clicking on things I started getting this error:

System.Configuration.ConfigurationErrorsException: Could not load file or assembly ‘Microsoft.ReportingServices.SharePoint.ObjectModel’ or one of its dependencies. The located assembly’s manifest definition does not match the assembly reference

Icky. So a web search turned up one hit, a connect item filed by Brian Judge:

https://connect.microsoft.com/SQLServer/feedback/details/1088671/sql-server-2012-reporting-services-errors-after-installing-sql-server-2014

At the bottom, Brian gives the clue on how to fix the issue when he says:

If I change the redirect to stay on 11.0.0.0 for the following policies then the problem appears to be resolved:

C:\Windows\assembly\GAC_MSIL\Policy.11.0.Microsoft.ReportingServices.SharePoint.ObjectModel

C:\Windows\assembly\GAC_MSIL\Policy.11.0.Microsoft.ReportingServices.SharePoint.Server

C:\Windows\assembly\GAC_MSIL\Policy.11.0.Microsoft.ReportingServices.SharePoint12.Server

C:\Windows\assembly\GAC_MSIL\Policy.11.0.Microsoft.ReportingServices.SharePoint14.Server

 

Alas, there are no specific instructions on just how to change the redirect. For those not familiar with the way these things work, I wanted to amplify his fix.

First, open a command window in administrator mode. I used the one that came with Visual Studio (the Developer Command Prompt for VS2012).

Next, change directory by using the “cd” command to the first item in the list above. (Click on the pic for a bigger image, should you have poor eyesight).

image

Using the DIR command, we can see one directory with a version number followed by what appears to be a hash value of some type. Issue another CD into that folder.

image

Using the DIR command again you will find two files in that folder:

image

Use notepad to edit the one with the .config extenstion.

image

When it appears, you will see something like:

image

Simply change the number in the newVersion from 12, to 11.

image

Repeat the steps for all four of the folders in the list above.

Next, and this is important kids, you need to stop and restart your SQL Server 2012 Reporting Services service, or simply reboot the computer. After that, your SSRS 2012 Report Manager should start to behave normally again. I’ve also tested the 2014 Report Manager, and it seems to work fine after the changes were applied. (In theory it shouldn’t have been affected, but you can never be too careful).

If you found this post useful, do us a favor. Go to the Microsoft Connect article linked at the top and give it an up vote, so Microsoft will begin to take notice. Also thanks again to Brian Judge (whom I do not know but hope to meet) for filing the original bug and giving the clue to fixing it.

So You Think MDX is Hard? Presented at SQL Saturday Nashville Jan 17 2015

At SQL Saturday Nashville, on January 17 2015, I presented “So You Think MDX is Hard?”. Unfortunately the SQL Saturday website is having issues with code samples, so I have uploaded the presentation to my Technet Code site. You will find it at http://bit.ly/acmdx

Inside are three files, a PDF of the slide deck, the MDX script I ran, and the analysis services database as a backup file (abf) that you can restore to a server on which you have administrative rights. This sample was created in SQL Server 2012, although should work on 2014 and (although I haven’t tested) should work on 2008R2.

SQL Server SSIS SSDT Error – Method Not Found: Microsoft.SqlServer.Dts.Design.VisualStudio2012Utils.IsVisualStudio2012ProInstalled

Every so often, especially when setting up a new virtual machine, at some point I get this error when working in SSIS:

 

image

 

It happens often enough that, to be honest, I mostly wanted to make this as a record to myself and friends, but I am hopeful that you will be helped as well. And to give credit where it is due, I found the original answer at Stack Exchange:

http://stackoverflow.com/questions/24745396/isvisualstudio2012proinstalled-method-not-found-error-when-running-an-ssis-pac

The steps are pretty straight forward.

1.  First, if you have Visual Studio open, close it.

2. In the classic Windows menu go to Start, All Programs, Microsoft Visual Studio 2012, Visual Studio Tools, and right click on the “Developer Command Prompt for VS2012” and pick “Run as administrator”. If you are in Windows 8 or Server 2012 or later, probably easiest to just do a search for “Developer Command Prompt for VS2012”.

3. Navigate to Visual Studio’s Private Assemblies folder by entering “CD C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\PrivateAssemblies”  (If you have installed VS to another drive or folder, adjust the path accordingly).

4. Enter the command “gacutil /if Microsoft.SqlServer.Dts.Design.dll” into the command prompt.

 

image

 

Now you should be able to open your SSIS projects.

The dll is the main set of libraries for SQL Server Integration Services. For some reason, after certain Windows updates, this becomes deregistered and you have to manually add it back. Not a huge deal, but annoying if it happens often enough. As I just had it happen today after a Windows update to the Hyper-V VM I use for some of my SQL Server development, I wanted to post this as a reminder on how to correctly fix the issue.

Get Your “Gangsta Geek” On, and Help A Kid!

GangstaGeek At the 2014 PASS Summit, Pragmatic Works Gangsta Geek shirts were incredibly popular. Looking at the number of boxes we brought, I would have thought there was enough for the entire week. Yet, by the end of day 1 they were gone.

If you missed out at the summit, or just think it’s a really cool shirt (because it is!) then now is your chance to get one and help a kid in the process.

Until December 5th, 2014 Pragmatic Works is donating 100% of the proceeds from sales of the shirts (minus shipping) to Seamark Ranch, an organization which provides secure homes from children that come families in crisis. You can go here to find out more and order your shirt! Don’t wait to get your Gangsta on, you only have a few days left!

Goodbye Pragmatic Works. Hello Pragmatic Works!

I wanted to share a new phase in my life. After a little over three and a half awesome years, October 10th will be my last day as a consult with Pragmatic Works. Beginning October 13th I will be going to work for… Pragmatic Works! (Confused? Hey you should be me.)

Most people don’t realize this, but Pragmatic Works is technically two companies in one. We have a consulting division, where I have worked for the last three and a half wonderful years. Beginning October 13th I will transition to working for the software division in the role of Product Evangelist.

In this role I will be spreading the word about our tools, as well as supplying additional training on our entire suite. You can begin to expect more posts from me that focus on our various tools, which include BIxPress, Task Factory, DOCxPress, and DBAxPress. I’ll still be in the community, perhaps even more so, giving people the opportunity to learn more about SQL Server in general, our tools and services in particular.

If you are going to the PASS Summit, be sure to look me up. I’m copresenting a precon titled Zero to Hero with PowerShell and SQL Server, as well as doing a regular session Make SQL Server Pop with PowerShell. I’ll also be spending a lot of time at the Pragmatic Works booth doing demos and the like. Would love to meet you, talk about your challenges around BI development, and how we could work to get many of them resolved.

So, Goodbye Pragmatic Works. Hello Pragmatic Works!

Zero to Hero with PowerShell and SQL Server at 24 Hours of Pass

On September 9th I am co-presenting “Zero to Here with SQL Server and PowerShell” for the 24 Hours of PASS. If you’ve not heard of 24 Hours of PASS, it is 24 straight hours of online presentations. This time the sessions are a preview of the SQL PASS Summit in Seattle, WA in November.

At the PASS Summit I, along with two co-workers, am presenting a full day Pre-Con entitled Zero to Hero with PowerShell and SQL Server. I’m also doing a regular session, Make SQL Server POP with PowerShell.

The session for 24 Hours of PASS will take place at 00:00 GMT on September 10th, or for those of us in the states, September the 9th, 8 PM Eastern, 7 PM Central, 6 Mountain, or 5 Pacific. The session is titled the same as the precon, Zero to Hero with PowerShell and SQL Server. Through the preceding link you can see more about the session, get to the full schedule, and most importantly register!

Be sure to check out my co-presenters too, Bradley Ball (@SqlBalls | http://sqlballs.com ) and Jason Strate (@StrateSQL | http://www.jasonstrate.com )

PowerScripting Podcast

I just wanted to give a thanks to the guys at the PowerScripting Podcast for having me on tonight. As soon as it is released I’ll follow up with a link.

For those who came here from hearing me on the podcast, you can find more info on SQL Saturday at: http://bit.ly/sqlsat328

If you want to find out more about my sessions at the PASS Summit, you can jump to http://bit.ly/acsummit. My co-presenters for the precon are Brad Ball @sqlballs and Jason Strate @stratesql.

The Pragmatic Works webinars can be found on the company website at http://pragmaticworks.com. Just follow the Free Training on the T’s to get access to the webinars. You can search by author name (Robert Cain will get you mine) or topic.

My other training videos can be found on Pluralsight, http://pluralsight.com/training.

I also have a youtube channel with a couple of videos, https://www.youtube.com/user/arcanecode. Check out the Column Mode Editing video for a quick editing tip on making your life easier with both PowerShell and SQL Server.

SQL Saturday Jacksonville #298–So you think MDX is hard?

For SQL Saturday #298 in Jacksonville, FL on May 10, 2014 I am presenting “So you think MDX is hard?”.

A lot of people have this perception that MDX is difficult. It really isn’t, when you understand what it is trying to accomplish under the hood. In this session we’ll begin with a fundamental understanding of what MDX will do for you. Then we’ll roll up our sleeves and dive into MDX code, starting from the simplest select statement and winding up building calculations you can put into your own SSAS Cubes.

You’ll find the presentation slide deck and code at:

http://sqlsaturday.com/viewsession.aspx?sat=298&sessionid=19934

SQL Saturday Atlanta #285–Everything You Ever Knew About SSIS Is Null and Void

For the SQL Saturday #285 in Atlanta, May 3rd 2014, I am presenting “Everything You Ever Knew About SSIS Is Null and Void”. You’ll find the presentation itself at:

http://sqlsaturday.com/viewsession.aspx?sat=285&sessionid=19929

All of the SSIS samples including the simple SSIS packages, SQL Scripts, and Slides will be available there shortly.

The main pieces of code, the SQL scripts to  monitor SSIS, can also be found in my TechNet Gallery:

http://gallery.technet.microsoft.com/SQL-to-Monitor-and-Explore-e485fa84

Thanks for attending!