From Zero to ‘Hello, World!’ with C#

For the past year, or so, I have been diving head first in to Microsoft’s Azure cloud service platform. I started with infrastructure as a service (IaaS) and as I expected, it wasn’t much different that what I had been doing for the past decade and a half. Virtual machines and virtual networks in Azure aren’t much different than virtual machines and virtual networks on any other platform. The real value that Azure and many other cloud service providers offer is Platform as a Service or PaaS. The ability to build applications without having to worry about the underlying infrastructure. Focus on building cool stuff and let Microsoft, Google, Amazon, et al., worry about managing the hardware resources, operating systems, etc. Simple, right? Not exactly. I have spent the majority of my career racking, stacking, building out physical infrastructure, configuring virtualized environments, and then… well… no ‘and then’. Don’t get me wrong, I LOVE my job. I love unboxing a pile of shiny, new, expensive things (that I didn’t have to buy my self) and making it all work. However, as they say, times are a changin’. I want to learn how build cool [software] stuff. That’s way too broad. I need to focus…

I want to learn how to develop solutions on Microsoft’s Azure Platform, specifically around their many Platform as a Service offerings.

That’s better.

I have decided to start this adventure by learning the basics of C# (pronounced ‘see sharp’ and sometimes referred to as .NET). Microsoft has done a great job of providing development compatibility for many of the major programming languages. However, I have found that most of the documentation and tutorials that exist today are focused on C#.

Let’s get started.

Install Visual Studio 2017 Community Edition (Free)

Go to and download the ‘Community Edition’. During the install process, you will need to choose which workloads you would like to develop. For now, choose ‘ASP.NET and web development‘. Once the install completes, launch Visual Studio. You should see something like this:

Visual Studio

Create a new Visual Studio project

Navigate to File, New, and select ‘Project…’, select ‘Console App (.NET Core)‘ and name your project ‘HelloWorld‘.

VS New Project

At this point, you should see your new project workspace. Visual Studio creates some boiler plate code to get you started.

Hello World

Modify the ‘Program.cs’ code

Add the following statement to the ‘Program.cs‘ file: ‘Console.ReadLine();‘ on the line below ‘Console.WriteLine(“Hello World!”);‘. Note: C# is a case-sensitive language.

Read Line

Click the ‘Save‘ icon in the toolbar to save your modifications.

Run your ‘Hello World!’ program

Click the little green triangle in the main toolbar.  A console window should pop up and you should see ‘Hello World!’.

Hello Console

The ‘Console.ReadLine’ statement we added is causing the application to wait for input. Without this bit of code, the console window closes too quickly.

To close the application, click in the console window, and push the enter or return key.

Congrats to those of you following along at home. We just wrote our first program in C#. That was almost too easy. I guess we have to start somewhere, right?

I’ll be posting my code over on Github for reference. You can find my Github profile over here:

Here are a few learning resources that I have found:

Questions? Comments? Helpful advice for a developer in training? Leave a comment below or hit me up on Twitter.


Introducing OnCommand Shift

Have you ever tried to migrate a virtual machine from one hypervisor to another? If so, you will have quickly realized that it isn’t as easy as it should be. In a time of software defined everything, you would hope that converting a virtual machine from one hypervisor format to another would be fairly straight forward. Until now, it has been a very painful process requiring complete data copies, extended periods of downtime, and costly migration tools.

Today, NetApp is changing the game. Again.


OnCommand Shift is a new tool released today that allows you to quickly and easily migrate or “Shift” your virtual machines from one hypervisor to another. Do you want to know the best part? NetApp is providing this tool free of charge.

Say What?

Yes, the tool is free. FREE.

The initial release of OnCommand Shift supports VMware ESXi 5.0 (and newer) and Windows Server 2008 R2 Hyper-V (and newer) and requires a FAS2240 or newer controller running Clustered Data ONTAP 8.2 or later.

OnCommand Shift uses several technologies under the covers to provide a conversion process that is simple, cost effective, and most importantly, FAST.

Here is an overview of the process:
1. Collect data
2. Snapshot VM
3. Remove hypervisor integration tools
4. Migrate VM
5. Configure networking

Seems pretty simple, right? I know what you are probably thinking…”How is this faster or different that those other migration tools?”

The magic is how OnCommand Shift leverages the power of Clustered Data ONTAP. The process uses NetApp’s FlexClone technology to make a writable space efficient clone of the virtual machine and then generates the new metadata needed to convert the virtual machine from one hypervisor to another. The process takes only a few minutes. Once complete, you are left with a converted virtual machine that takes up only a tiny amount of extra space.


For more information:

OnCommand Shift Data Sheet:

NetApp Communities Blog Post: OnCommand Shift Blog

You can download OnCommand Shift here:  OnCommand Shift Download

Look for another post soon that will include more technical details as well as a demo.

Happy Shifting!

NetApp EF560 and E5600 Link Roundup!

NetApp's EF560 All-Flash Array
While the Northeast goes into a deep freeze, NetApp has thrown another Flash Grenade! Today, NetApp announced an update to their E-Series SAN arrays along with some amazing SPC-1 results! I have gathered all of the blog posts, news articles, and spec sheets that I could find in one place.

First and foremost, the SPC-1 results:

tl;dr: 650,000 IOPs at sub .8ms latency! (24x400GB SSD)

Blogs / News:

NetApp Technical Reports (TR)

NetApp Datasheets:

3D Interactive Demos:

Still simple, still reliable, but now faster, more cost-effective, and with more features…NetApp E-Series

Replicate igroup Information from Old Controller to New (7-Mode)

As much as I would like to exclusively be working with Clustered Data ONTAP, there are still times where I need to work with 7-Mode. As many storage admin and consultants know, hardware refreshes can be quite time consuming. This is a quick and dirty script I wrote to save some time recreating Initiator Groups on a new 7-Mode storage system. Modify the first two lines with the source and target controllers and go. The script isn’t very complex, but it sure can save a ton of time.

$SourceController = "sourceIPHostname"
$TargetController = "targetIPHostname"

Connect-NaController $SourceController

$Igroups = Get-NaIgroup

Connect-NaController $TargetController

$Igroups | New-NaIgroup

ForEach($Igroup in $Igroups) {
	$Initiators = $Igroup.Initiators
	ForEach($Initiator in $Initiators) {
		Add-NaIgroupInitiator $Igroup $Initiator

List all Volumes on all Controllers (7-Mode)

Volumes: The flexible storage containers of Data ONTAP. They can be resized, deduplicated, compressed, and even FlexCloned. But first, let’s just see which ones we have.

Several PowerShell one-liners will require a text file that I will refer to as NaList.txt. This file is simply a list of all the NetApp controllers in your environment, one per line:

PS C:\Scripts> Get-Content NaList.txt

Finally, the code:

Get-Content NaList.txt | ForEach-Object {Connect-NaController $_; Get-NaVol | Format-Table}

Now, the output:

Name                 Address           Ontapi   Version
----                 -------           ------   -------
netapp1        1.14     NetApp Release 7.3.6: Thu Jul  7 02:02:45 PDT 2011

Name                      State       TotalSize  Used  Available Dedupe  FilesUsed FilesTotal Aggregate
----                      -----       ---------  ----  --------- ------  --------- ---------- ---------
backup                    online        80.0 GB   24%    60.6 GB False         102         3M aggr0
vol0                      online         8.8 GB   15%     7.5 GB False         11k         7M aggr0

Name                 Address           Ontapi   Version
----                 -------           ------   -------
netapp2        1.14     NetApp Release 7.3.6: Thu Jul  7 02:02:45 PDT 2011

Name                      State       TotalSize  Used  Available Dedupe  FilesUsed FilesTotal Aggregate
----                      -----       ---------  ----  --------- ------  --------- ---------- ---------
vol0                      online         8.8 GB   15%     7.5 GB False         11k         7M aggr0

Now let’s make the code as short as possible by removing unnecessary spaces and utilizing PowerShell’s built in command aliases:

gc NaList.txt|ForEach{Connect-NaController $_;Get-NaVol|ft}

My attempt to explain the command in plain english: Get-Content (gc) reads the contents from NaList.txt and then pipes each line (controller) as an object to the ForEach-Object (foreach) command. Then for each object (controller) we issue Connect-NaController $_ ($_ represents the current object) and then issue the Get-NaVol command and finally pipe that output to the Format-Table (ft) function in order to get the nice easy to read tabular layout.

That’s it. Now you have a simple way to get a master list of every volume in your NetApp environment.

Questions? Comments? Do you think this could be done better? with less code? Let me know in the comments, please!

List all Snapshots and Export to CSV (7-Mode)

Inspired by this post written by Yann Bizeul (@ybontap), I decided to provide an example of the NetApp PowerShell Toolkit command required to get the equivalent output.

The goal of Yann’s exercise was to gather a list of snapshots and format them in a way that was easy to cut and paste into an Excel spreadsheet.

First a look at Yann’s shell command:

ssh root@ snap list -n|tr -d '\r' | sed -n -E '{/^Volume /{N;N;N;s/\n/ /g;s/.*Volume ([^ ]*).*/\1/;h;};/^---/,/^$/{/^---/d;/^$/d;G;s/(.*) (..:..)  (.*)\n(.*)/\4      \1      \2      \3/g;p;};}'

The NetApp PowerShell equivalent exported to a CSV file:

PS C:\Scripts> Connect-NaController netapp01; Get-NaVol | Get-NaSnapshot | Select-Object TargetName,Created,Name | Export-CSV -Path outfile.csv

Yann’s command works great and is very useful if you have access to a *nix shell and you are proficient in sed. However, I think it is clear how much effort could be saved by taking advantage of the NetApp PowerShell Toolkit.

Finally, I would like to thank Yann for his imformative post and I encourage you to check out his blog for more great NetApp info: YB Ontap

NetApp PowerShell Toolkit: Getting Started

Welcome! I am in the process of learning PowerShell and more specifically the NetApp PowerShell Toolkit. I’ll post one-liners, simple scripts, tips, and resources I discover along the way. If you are a NetApp storage administrator and you haven’t taken the NetApp PowerShell Toolkit for a spin yet, I highly recommend you do so. The PowerShell language combined with the Data ONTAP API is a powerful tool that can be used to document, manipulate and even automate your storage environment.

Getting setup with NetApp’s PowerShell Toolkit is very simple. More info can be found here. You will need to login to download the DataONTAP.msi installer.

Once you get the toolkit installed properly, you should be able to type “Get-NaHelp” to see a list of NetApp commandlets.

The first few lines of the Get-NaHelp command should look something like this:

PS C:\Scripts> Get-NaHelp

Name                                Category        Api
----                                --------        ---
Add-NaAggr                          aggr            {aggr-add}
Add-NaCifsShare                     cifs            {cifs-share-add}
Add-NaCredential                    toolkit
Add-NaFpolicyExtension              fpolicy         {fpolicy-extensions}

All of the NetApp commandlets are in the format “Verb-NaNoun” for 7-Mode and “Verb-NcNoun” for Clustered ONTAP.

To get help with a specific commandlet use the standard Microsoft “Get-Help” commandlet followed by the NetApp commandlet:

PS C:\Scripts> Get-Help Get-NaVol


    Get volume status.

    Get-NaVol [[-Names] <String[]>] [-Aggregate <String>] [-Terse] [-Controller <NaController>] [<CommonParameters>]

    Get volume status.  Note that all RAID-related status items (e.g., 'raid-size', 'raid-status', 'checksum-style')
    reported for a flexible volume actually describe the state of its containing aggregate.


    To see the examples, type: "get-help Get-NaVol -examples".
    For more information, type: "get-help Get-NaVol -detailed".
    For technical information, type: "get-help Get-NaVol -full".

Most of the commandlets require you to first connect to a NetApp controller using the “Connect-NaController” commandlet:

PS C:\Scripts> Connect-NaController

Name                 Address           Ontapi   Version
----                 -------           ------   -------
netapp1        1.14     NetApp Release 7.3.6: Thu Jul  7 02:02:45 PDT 2011

Hopefully that is enough info to get you started if you are completely new to the NetApp Toolkit. If not, feel free to ask for help in the comments or on the NetApp Communities website.

Subscribe via RSS or follow me on Twitter (@seanluce) for updates.

Happy Scripting!