posts - 104 , comments - 115 , trackbacks - 0

My Links

News

Disclaimer: Right here... Github: Code all the things! PS GUI Series: < Coming Soon! > PS Scripts: < Coming Soon! >

Tag Cloud

Article Categories

Archives

Post Categories

Image Galleries

Blogs

Forums

Lync

Storage

Tools

Virtualization

Web comics

Monday, March 11, 2019

No one takes you seriously when you are young

There is something that we all share, something that frustrates us immensely. It's not being taken seriously… Well, there's probably more things that frustrate us immensely, but today I want to talk specifically about the relationship between age and being taken seriously.

I came upon a discussion thread on reddit and was reminded of what I went through when I entered my career. I was also reminded of all the times friends, colleagues, and even family shared this with me:

"Our views are being dismissed because we're young."

There is truth in this. Often times you'll see that your professional opinion is not taken seriously or dismissed entirely. Us youngsters feel that this is because we are young, haven't paid our dues, or whatever other reason we attribute to it.

When I was 20 something, I too encountered this quite a lot and had a hard time understanding why… After all, if I wasn't at work, I was trying to get a deeper understanding of technology in my home lab, reading whitepapers, and could support my statements with solid proof of it being valid.

But still I was being ignored or dismissed.

But then there came a moment in my career a lightbulb went off. It was when a former colleague of mine appeared at a customer I was working with. Now I have to say, this man was always a smart cookie. I looked up to him immensely, and in a way I still do. He had gone on to work at Microsoft as a Premier Field Engineer, and as such he arrived with a truckload of authority in a meeting I was quietly attending (I stopped proposing solutions or workarounds to issues at that point). A question was posed to him and he said "That's slightly out of my field of knowledge, but why don't you ask Marc about that, he probably knows the answer to that."

To this day I don't know if he just wanted to make me look good, or he genuinely did not know, but that line stuck in my head forever, because what happened after that was an eye opener. I answered the question without missing a heartbeat, supported it with referencing where this information could be found, and supplying that information (as well as a detailed answer to the question) to the attendees of the meeting afterwards.

It also dawned upon me that suddenly, by virtue of an SME giving me the opportunity to speak up, I was also considered an SME by the people in that meeting, and they pulled me in to other meetings to help out with other items, and they provided me with the backing to be taken seriously.

What happened? What suddenly changed? I didn't become more knowledgeable because he said I could answer a question he didn't know the answer to. I was given credit by someone who knew me from a previous company and had a position of authority.

So, the next company I worked at I encountered the same issues again. I sat down and thought about that moment. I sat down and thought about how to replicate the situation of being taken seriously. I came to the realization that if nobody knows what you know, you won't be taken seriously. Your resume gets you hired, but what you know gets you interesting projects and challenges.

I started to force myself to share more with colleagues, offered my ear in rubber ducking (the act of explaining a problem to yourself or someone else often helps in coming to a solution), and would help diagram/solve issues people outside of my direct team would have. In other words, I built a name for myself outside of my direct team. More and more I was pulled in to projects, and my voice was not dismissed outright.

Obviously, I had my set-backs, my ups and downs, and had (and still have) much more to learn. But it was a spark that was lit in my brain, a new neural connection created, an interest in interpersonal communication and social dynamics that I have explored since then. Growing is more a process of discovering what not does not work, or should not be done.

Later in my career, I had the opportunity to start in the same role as that man that turned on my lightbulb, and gave me a voice in a room. I tried to do the same thing for others, as he (knowingly or unknowingly) did for me. I helped them gain a voice in a room, where they previously were dismissed.

To this day, I am grateful for that moment, Benjamin Logist. And I say thank you, for teaching me something that day! You helped me realize that my voice was not lost because I was young, but because I did not have to social credit, or the backing of someone with that credit to have it heard.

Since that moment, I have encountered many people who helped come to many realizations, taught me a great deal on both technical and social topics. To all of them I say "Never stop teaching"!

 

Posted On Monday, March 11, 2019 2:07 PM | Comments (0) |

Tuesday, February 19, 2019

[Powershell Series] Creating Graphical User Interfaces – Working with rows and columns

Rows and columns are things I've recently started to dive in to since I was getting fairly annoyed when I was building larger user interfaces. They're pretty powerfull, but it took me a while to get my head around the capabilities… In essence you are setting up your grid element(s) to have predefined sizes, and drop working with the margin properties so whatever control you place in a row or column takes it up completely.

Also, it prevents your controls from changing position and size when you're resizing a window, as well as making alignment of controls easier. Pretty neat!

The start

So let's say we've built a nice little basic GUI to show some information.

Represented by the following XAML code:

<Window

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

x:Name="MainWindow"

Title="Rows and Columns"

Height="217.893"

Width="392.894"

>

 

<!-- Grid area -->

<Grid Margin="0,0,0,0">

<!-- A Label -->

<Label x:Name="lblLabel" Content="Label" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="52"/>

<!-- A Button -->

<!-- A Textbox -->

<TextBox x:Name="txtTextBox" HorizontalAlignment="Left" Height="20" Margin="67,14,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>

<Label x:Name="lblLabel0" Content="Label" HorizontalAlignment="Left" Margin="10,36,0,0" VerticalAlignment="Top" Width="52"/>

<Label x:Name="lblLabel1" Content="Label" HorizontalAlignment="Left" Margin="10,62,0,0" VerticalAlignment="Top" Width="52"/>

<Label x:Name="lblLabel2" Content="Label" HorizontalAlignment="Left" Margin="10,88,0,0" VerticalAlignment="Top" Width="52"/>

<TextBox x:Name="txtTextBox0" HorizontalAlignment="Left" Height="20" Margin="67,39,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>

<TextBox x:Name="txtTextBox1" HorizontalAlignment="Left" Height="20" Margin="67,64,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>

<TextBox x:Name="txtTextBox2" HorizontalAlignment="Left" Height="20" Margin="67,88,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>

<Label x:Name="lblLabel3" Content="Label" HorizontalAlignment="Left" Margin="202,10,0,0" VerticalAlignment="Top" Width="52"/>

<Label x:Name="lblLabel4" Content="Label" HorizontalAlignment="Left" Margin="202,35,0,0" VerticalAlignment="Top" Width="52"/>

<Label x:Name="lblLabel5" Content="Label" HorizontalAlignment="Left" Margin="202,64,0,0" VerticalAlignment="Top" Width="52"/>

<Label x:Name="lblLabel6" Content="Label" HorizontalAlignment="Left" Margin="202,88,0,0" VerticalAlignment="Top" Width="52"/>

<TextBox x:Name="txtTextBox3" HorizontalAlignment="Left" Height="20" Margin="254,14,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>

<TextBox x:Name="txtTextBox4" HorizontalAlignment="Left" Height="20" Margin="254,40,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>

<TextBox x:Name="txtTextBox5" HorizontalAlignment="Left" Height="20" Margin="254,66,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>

<TextBox x:Name="txtTextBox6" HorizontalAlignment="Left" Height="20" Margin="254,92,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>

 

</Grid>

</Window>

Creating columns and rows

It's fairly easy to add in Columns and Rows in to your GUI, it's as simple as adding a few tags right under the <Grid> tag:

<Grid>

<Grid.ColumnDefinitions>

</Grid.ColumnDefinitions>

<Grid.RowDefinitions>

</Grid.RowDefinitions>

</Grid>

 

But this obviously doesn't create a row or column! It merely sets up the scaffolding for us to start defining them… In order to add a column or row we need to use the <RowDefinition Height=""/> or <ColumnDefinition Width=""/> tag.

 

In our case I want to have an edge of 10 pixels wide around our borders which would mean my top and bottom rows need a height of 10, and the left and right columns need a width of 10. For the labels I will use a width of 100 pixels, whilst the textboxes columns will get a width of 150. Since I don't want the labels on the right side to but up to the textboxes of the left side I will put in a column to separate them.

 

That would mean our grid code would look like this:

 

<Grid Margin="0,0,0,0">

<Grid.ColumnDefinitions>

<ColumnDefinition Width="10"/>

<ColumnDefinition Width="50"/>

<ColumnDefinition Width="100"/>

<ColumnDefinition Width="5"/>

<ColumnDefinition Width="50"/>

<ColumnDefinition Width="100"/>

<ColumnDefinition Width="*"/>

<ColumnDefinition Width="10"/>

</Grid.ColumnDefinitions>

<Grid.RowDefinitions>

<RowDefinition Height="10"/>

<RowDefinition Height="30"/>

<RowDefinition Height="30"/>

<RowDefinition Height="30"/>

<RowDefinition Height="30"/>

<RowDefinition Height="30"/>

<RowDefinition Height="*"/>

<RowDefinition Height="10"/>

</Grid.RowDefinitions>

</Grid>

 

Which looks like this in the GUI:

 

You've probably noticed I created a row and a column where the height and width property are set to "*". I call them filler rows/columns, since they will take up all the space that's still available in your window size.

 

Hey! Where did my controls go?!

Oh you noticed? Good! By default, all controls seem to live in Row 0, Column 0. So if you create columns and rows, your controls will still be there, you just won't be able to see them… But let's get that fixed now! Let's start with our very first label:

<Label x:Name="lblLabel" Content="Label" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="52"/>

There's a few properties we'll need to remove to meet our criteria of filling the space, and a few to add so it get's bound to a row and column

<Label x:Name="lblLabel" Grid.Row="1" Grid.Column="1" Content="Label" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />

As you can see, I've added 2 tags: Grid.Row and Grid.Column. Both of these place your control in the respective values (and they start counting from 0!). I've also set the HorizontalAlignment and VerticalAlignment properties to stretch, so the label would take up all the space available, and removed my margin and width properties, since they're no longer needed… Rinse and repeat for all controls and you're gui will end up looking like this:

And the code:

<Window

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

x:Name="MainWindow"

Title="Rows and Columns"

Height="217.893"

Width="392.894"

>

 

<!-- Grid area -->

<Grid Margin="0,0,0,0">

<Grid.ColumnDefinitions>

<ColumnDefinition Width="10"/>

<ColumnDefinition Width="50"/>

<ColumnDefinition Width="100"/>

<ColumnDefinition Width="5"/>

<ColumnDefinition Width="50"/>

<ColumnDefinition Width="100"/>

<ColumnDefinition Width="*"/>

<ColumnDefinition Width="10"/>

</Grid.ColumnDefinitions>

<Grid.RowDefinitions>

<RowDefinition Height="10"/>

<RowDefinition Height="30"/>

<RowDefinition Height="30"/>

<RowDefinition Height="30"/>

<RowDefinition Height="30"/>

<RowDefinition Height="30"/>

<RowDefinition Height="*"/>

<RowDefinition Height="10"/>

</Grid.RowDefinitions>

<!-- A Label -->

<Label x:Name="lblLabel" Grid.Row="1" Grid.Column="1" Content="Label" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />

<!-- A Button -->

<!-- A Textbox -->

<TextBox x:Name="txtTextBox" Grid.Row="1" Grid.Column="2" HorizontalAlignment="stretch" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Center" />

<Label x:Name="lblLabel0" Grid.Row="2" Grid.Column="1" Content="Label" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />

<Label x:Name="lblLabel1" Grid.Row="3" Grid.Column="1" Content="Label" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />

<Label x:Name="lblLabel2" Grid.Row="4" Grid.Column="1" Content="Label" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />

<TextBox x:Name="txtTextBox0" Grid.Row="2" Grid.Column="2" HorizontalAlignment="Stretch" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Center" />

<TextBox x:Name="txtTextBox1" Grid.Row="3" Grid.Column="2" HorizontalAlignment="Stretch" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Center" />

<TextBox x:Name="txtTextBox2" Grid.Row="4" Grid.Column="2" HorizontalAlignment="Stretch" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Center" />

<Label x:Name="lblLabel3" Grid.Row="1" Grid.Column="4" Content="Label" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />

<Label x:Name="lblLabel4" Grid.Row="2" Grid.Column="4" Content="Label" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />

<Label x:Name="lblLabel5" Grid.Row="3" Grid.Column="4" Content="Label" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />

<Label x:Name="lblLabel6" Grid.Row="4" Grid.Column="4" Content="Label" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />

<TextBox x:Name="txtTextBox3" Grid.Row="1" Grid.Column="5" HorizontalAlignment="Stretch" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Center" />

<TextBox x:Name="txtTextBox4" Grid.Row="2" Grid.Column="5" HorizontalAlignment="Stretch" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Center" />

<TextBox x:Name="txtTextBox5" Grid.Row="3" Grid.Column="5" HorizontalAlignment="Stretch" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Center" />

<TextBox x:Name="txtTextBox6" Grid.Row="4" Grid.Column="5" HorizontalAlignment="Stretch" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Center" />

</Grid>

</Window>

 

But what if you have a control that needs to span different columns? For example a button?

 

 

By default, it will not show half of the button. But you can use the Grid.ColumnSpan property to overcome this nasty little problem…

<Button x:Name="btnButton" Grid.ColumnSpan="5" Content="Button" Grid.Column="1" HorizontalAlignment="stretch" Grid.Row="5" VerticalAlignment="center" />

And just so you know, there's a Grid.RowSpan as well!

<Button x:Name="btnButton" Grid.ColumnSpan="5" Content="Button" Grid.Column="1" HorizontalAlignment="stretch" Grid.Row="5" Grid.RowSpan="2" VerticalAlignment="stretch" />

Just know that when you're using these properties on a control, that control will seemingly merge the rows and columns that you tell it to span, and the vertical and horizontal alignment will apply to that "merged" column/row.

Also those blue lines don't show up in your actual tool when you launch it:

They're just there to help you visualize them

That's all folks!

And with that comes the end of this post in the series on Creating Graphical User Interfaces. I hope you enjoyed yourself, learned something new, or gained a greater understanding of our topic.
Until next time!

https://www.youtube.com/watch?v=gBzJGckMYO4

Posted On Tuesday, February 19, 2019 12:22 PM | Comments (0) | Filed Under [ Powershell #GUIBuilding #XAML #Rows #Columns #TimeToGetNeat ]

[Powershell Series] Creating Graphical User Interfaces – The basics

So, you've been writing PowerShell Scripts that interact with users and figured
"Hey, I really don't want to listen to the complaints that this it is archaic to use
a menu structure in the console" anymore, or perhaps you just want to learn something new .

This article aims to give you the basics to create a simple Windows Presentation Framework
form (using XAML) and presenting it to your user.

First things first… What is XAML?

XAML stands for eXtensible Application Markup Language, and it's Microsoft's variant of XML
for describing a Graphical User Interface. Previously you would use something like WinForm (shudder),
which would create the GUI in the same language that you would use to interact with the GUI.
WinForms doesn't scale well and is (in my opinion) horrible to work with.

The Editor of choice

There's quite a few editors you can use to create to make XAML windows (notepad being the most basic
one if you're feeling adventurous… ), but I prefer Visual Studio for my work. It helps that it comes with
my MSDN subscription, but there are other fine editors out there if you would choose to use a different
one. If you do decide to use Visual Studio, I highly recommend the PowerShell plug-in:
https://marketplace.visualstudio.com/items?itemName=AdamRDriscoll.PowerShellToolsforVisualStudio2017-18561

The good stuff

Your first window!

Yup, I use a Dark Theme … So what we see here is a number of different elements:

  1. The window
  2. The grid
  3. A label
  4. A textbox
  5. A button
  6. An image

Easy so far right? But how to we create these in XAML? By using the following XAML code:

<Window

 

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="MainWindow"

Height="204.683"

Width="525">

 

<!-- Grid area -->

<Grid>

<!-- A Label -->

<Label Content="Label" HorizontalAlignment="Left" Margin="68,38,0,0" VerticalAlignment="Top" Width="197"/>

<!-- A Button -->

<Button Content="Button" HorizontalAlignment="Left" Margin="307,41,0,0" VerticalAlignment="Top" Width="75"/>

<!-- A Textbox -->

<TextBox HorizontalAlignment="Left" Height="23" Margin="127,41,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>

<!-- An Image -->

<Image HorizontalAlignment="Left" Margin="198,106,0,10" Width="58" Source="C:\Users\Marc\Downloads\Cylon_Head.png" />

</Grid>

</Window>

Great! But what the hell does all of it mean?

<Window> </Window>

This is where it all starts. It allows users to interact with the application, and try to break it. The window tag
consists of a client, and non-client area. The non-client area is implemented by WPF and includes the part of
a window that are common to most windows: A border, title bar, icon, Minimize, Maximize, restore, close
buttons, and of course a system menu

The client area is where app specific content is added. Meaning, that's the area number 2 and above in the
picture from earlier live.

Properties

A full list of all the properties can be found here:
https://docs.microsoft.com/en-us/dotnet/api/system.windows.window?view=netframework-4.7.2

Typically, there's a few you would use to customize the window most commonly:

  • Title: This property will define the main name of your GUI
  • Height: Surprisingly, this defines the height of the GUI
  • Width: Defines the width of the GUI
  • Background: Defines the color of the client area
  • Borderbrush: The color your border should have
  • BorderThickness: How large your border should get
  • FontFamily: Sets the font for the client area
  • FontSize: Sets the size of the fonts in the client area

For example, changing the XAML code from early to this:

<Window

 

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="Just a demo"

Height="204.683"

Width="525"

Background="Red"

BorderBrush="Blue"

BorderThickness="4"

FontFamily="Algerian"

FontSize="24"

>

 

<!-- Grid area -->

<Grid>

<!-- A Label -->

<Label Content="Label" HorizontalAlignment="Left" Margin="21,31,0,0" VerticalAlignment="Top" Width="197"/>

<!-- A Button -->

<Button Content="Button" HorizontalAlignment="Left" Margin="307,41,0,0" VerticalAlignment="Top" Width="127"/>

<!-- A Textbox -->

<TextBox HorizontalAlignment="Left" Height="32" Margin="127,41,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>

<!-- An Textbox -->

<Image HorizontalAlignment="Left" Margin="198,106,0,10" Width="58" Source="C:\Users\Marc\Downloads\Cylon_Head.png"/>

</Grid>

</Window>

Would result in this:

All this building is fun and games, but how do we actually use it?

Actually calling it all from Powershell is quite simple. Generally you'll see 2 different approaches on this. One would be to define the XAML code in your PowerShell script as such:

[XML]$xaml=@"

<Window

 

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="Just a demo"

Height="204.683"

Width="525"

Background="Red"

BorderBrush="Blue"

BorderThickness="4"

FontFamily="Algerian"

FontSize="24"

>

 

<!-- Grid area -->

<Grid>

<!-- A Label -->

<Label Content="Label" HorizontalAlignment="Left" Margin="21,31,0,0" VerticalAlignment="Top" Width="197"/>

<!-- A Button -->

<Button Content="Button" HorizontalAlignment="Left" Margin="307,41,0,0" VerticalAlignment="Top" Width="127"/>

<!-- A Textbox -->

<TextBox HorizontalAlignment="Left" Height="32" Margin="127,41,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>

<!-- An Textbox -->

<Image HorizontalAlignment="Left" Margin="198,106,0,10" Width="58" Source="C:\Users\Marc\Downloads\Cylon_Head.png"/>

</Grid>

</Window>

"@

 

Other like keeping the xaml code in a separate xaml file and import it:

[xml]$xaml = Get-Content -Path "$($VariableHash.FormsDir)\MainWindow.xaml"

 

Personally, that last one is the one I prefer. Full code to show your gui:

# Loading required assemblies    

Add-Type –assemblyName PresentationFramework # Required to show the GUI

 

# Loading XAML code    

[xml]$xaml = Get-Content -Path "<Path to XAML file>"

 

    # Adding proper namespace

    $manager = New-Object System.Xml.XmlNamespaceManager -ArgumentList $xaml.NameTable

$manager.AddNamespace("x", "http://schemas.microsoft.com/winfx/2006/xaml");

        

# Loading in to XML Node reader

$Reader= New-Object System.Xml.XmlNodeReader $xaml

        

# Loading XML Node reader in to $SyncHash window property to launch later

$window = [Windows.Markup.XamlReader]::Load($reader)

 

# Show the window!

$window.ShowDialog()

Just one more thing…

Right now, you won't be able to do much with the above code. There are no names defined, nor event actions… So for each element that we want to interact with we should add a Name property:

<Window

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

x:Name="MainWindow"

Title="Just a demo"

Height="204.683"

Width="525"

Background="Red"

BorderBrush="Blue"

BorderThickness="4"

FontFamily="Algerian"

FontSize="24"

>

 

<!-- Grid area -->

<Grid>

<!-- A Label -->

<Label x:Name="lblLabel" Content="Label" HorizontalAlignment="Left" Margin="21,31,0,0" VerticalAlignment="Top" Width="197"/>

<!-- A Button -->

<Button x:Name="btnButton" Content="Button" HorizontalAlignment="Left" Margin="307,41,0,0" VerticalAlignment="Top" Width="127"/>

<!-- A Textbox -->

<TextBox x:Name="txtTextBox" HorizontalAlignment="Left" Height="32" Margin="127,41,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>

<!-- An Textbox -->

<Image x:Name="imgImage" HorizontalAlignment="Left" Margin="198,106,0,10" Width="58" Source="C:\Users\Marc\Downloads\Cylon_Head.png"/>

</Grid>

</Window>

Now that you have them named, you can connect the controls to variables (otherwise you cannot use them…):

#region connecting controls

$MainWindow = $Window.FindName("MainWindow")

$label = $Window.FindName("lblLabel")

$TextBox = $Window.FindName("txtTextBox")

$Button = $Window.FindName("btnButton")

$Image = $Window.FindName("imgImage")

#endregion connecting controls

For a button click, use the following:

#region Event Handling

    $Button.Add_Click({

        # Do something

    })

#endregion Event Handling

Which would make the full code:

 

# Loading required assemblies    

Add-Type –assemblyName PresentationFramework # Required to show the GUI

 

# Loading XAML code    

[xml]$xaml = Get-Content -Path "$PSScriptRoot\WpfWindow1.xaml"

 

    # Adding proper namespace

    $manager = New-Object System.Xml.XmlNamespaceManager -ArgumentList $xaml.NameTable

$manager.AddNamespace("x", "http://schemas.microsoft.com/winfx/2006/xaml");

        

# Loading in to XML Node reader

$Reader= New-Object System.Xml.XmlNodeReader $xaml

        

# Loading XML Node reader in to $SyncHash window property to launch later

$window = [Windows.Markup.XamlReader]::Load($reader)

 

#region connecting controls

$MainWindow = $Window.FindName("MainWindow")

$label = $Window.FindName("lblLabel")

$TextBox = $Window.FindName("txtTextBox")

$Button = $Window.FindName("btnButton")

$Image = $Window.FindName("imgImage")

#endregion connecting controls

 

#region Event Handling

    $Button.Add_Click({

        # Do something

    })

#endregion Event Handling

 

# Show the window!

$window.ShowDialog()

 

That's all folks!

And with that comes the end of this post in the series on Creating Graphical User Interfaces. I hope you enjoyed yourself, learned something new, or gained a greater understanding of our topic.
Until next time!

https://www.youtube.com/watch?v=gBzJGckMYO4

Posted On Tuesday, February 19, 2019 9:59 AM | Comments (0) | Filed Under [ Powershell #GUIBuilding #XAML ]

Monday, February 18, 2019

[Powershell Series] Creating Graphical User Interfaces

In this series I will go over everything I've learned to date about working with GUI's for PowerShell. Hopefully it will help you out with learning how to build user interfaces that are a bit more user friendly .

Posted On Monday, February 18, 2019 11:04 AM | Comments (0) |

It’s been a long time, my dear…

March the 28th, 2016. The date I published my last blog post… It's been a long time indeed. And in those mere 3 years a lot of things happened to my life. Not that that is supposed to be an excuse or anything, I've always been a poor blogger when it comes to consistently publishing .

Back in 2016, we still lived in California. We've bought, renovated, gotten a kid, sold, moved transatlantic, switched jobs, and bought again in the last 3 years when it comes to our personal life. As far as major life events go, that's quite a few of them in a very short time span… Yet we endured the way we always do. With heads high, minds clear and focused, and with a macabre sense of humor.

In 2017, I became a father to a miniature version of myself. Whether that's good or bad is yet to be determined, but so far, it's been both nerve wrecking and hilarious. With that happening, life priorities began to change, and while I absolutely loved the nature, sun, and people back in California, we decided that for the future of our child, as well as our own mental sanity (raising a kid without a real support network is exhausting) it would be in our best interest to move back to Europe.

In 2018, the decision was made that it would be the Netherlands we settle in, and the search for a new job was started. Both internally at Microsoft, and out in the "real" world. After many months of interviews and early morning calls (PST and GMT+1 don't really match up well), I decided to leave Microsoft to take on a Senior Cloud Architect role at Sogeti Netherlands, a choice that I made with a heavy heart as I absolutely loved working at Microsoft, especially with the stupidly smart people I had the privilege of working every day with. Not only did they challenge me to learn something new every day, they made me raise my own bar. Perhaps drove me to be slightly workaholic even. [S] Then again, doesn't everyone push 3 code updates in the middle of the nights to the staging branches for the tool you've been writing which would make your fellow engineers lives drastically easier? [/S]

And on August the 4th, 2018 I said goodbye. Goodbye to all my colleagues, to the customers I worked with over the years at Microsoft, to a bunch of great managers, and goodbye to an organization that I had seen evolve (the only constant is change ~ Brian Keane) and loved quite dearly. https://www.linkedin.com/pulse/thank-you-marc-dekeyser/

During the month of September we would fly to Amsterdam, look for a place to live, and try to get a new life going. September 1st I started at Sogeti Netherlands in Vianen (Utrecht… Apparently there's 2 Vianen in the country which confused the Volvo SatNav immensely!), and made an attempt to hit the ground running in 'Good Old PFE' style. And so I did… I've encountered new people, smart people, and interesting customers.

In 2019, so far we've bought another house, and renovations on that have started. A charming old 1928 house that needed some love. And love we shall provide it! This time for many years to come, as I'm absolutely through with moving around. A place for our little family to grow (old) and to make memories.

What the future of 2019 might hold, one can only guess. Hopefully a more consistent blog post line up, lots of challenging projects, personal growth, and lots of laughs. Thank you for being there all these years, thank you for watching me grow professionally, as well as personally, but most of all, thank you for being you. People in the IT field don't hear enough that they are awesome for putting in the hours, and dedication, for a role that mainly goes without praise. IT is the field that helps business grow and meet customer demands (when done right!), but in the end we serve the business as technology leaders.

Peace out,

Marc Dekeyser
Knowledge is Power, Wisdom is gaining Understanding.

Posted On Monday, February 18, 2019 9:57 AM | Comments (0) |

Monday, March 28, 2016

Script Browser & Script Analyzer

Good morning!

 

I randomly stumbled across these tools (Download link: https://www.microsoft.com/en-us/download/confirmation.aspx?id=42525). If you work with PowerShell scripting a lot these could be useful! The Script Browser allows you to browse the script repository from the PowerShell ISE directly, the Script Analyzer actually scans a script you write against recommended practices.

 

This is making my life a little bit easier, I hope it does the same for you!

Posted On Monday, March 28, 2016 3:06 PM | Comments (0) | Filed Under [ Powershell ]

Tuesday, March 22, 2016

O365 Selective licensing script

I finally digged-in and finished this script. It runs based on a CSV file allowing you to specify what user gets what modality enabled. I should probably start a git to manage my scripts better, but that'll have to wait until after my move...

Posted On Tuesday, March 22, 2016 6:40 PM | Comments (0) | Filed Under [ Powershell O365 scripting! ]

Thursday, October 22, 2015

Installing the Windows Azure Active Directory Synchronization Tool (a.k.a. DirSync)

Posted On Thursday, October 22, 2015 1:26 PM | Comments (0) | Filed Under [ Build Guides Deployment Office 365 ]

IIS ARR: Installing the reverse proxy server

Step 1: Open Server manager

Step 2: Install the “web server (IIS)” component. Accept all defaults.

step 3: Download the web platform installer

Step 4: Run the WPi

Step 5: Search for the Application Request Routing component

Step 6: Click on “Add” next to Application Request Routing 3.0

clip_image002

Step 7: Click on “Install

clip_image004

Step 8: Accept the Prerequisites list

clip_image006

Step 9: Wait for the download and installation to finish

clip_image008

Step 10: Click “Finish

clip_image010

Step 11: Open IIS manager

clip_image002[5]

Step 12: Select your server in the Internet Information Services (IIS) Manager

clip_image004[5]

Step 13: Select “Server Certificates

clip_image006[5]

Step 14: Verify the correct certificate is listed

clip_image008[5]

If the certificate is not listed, use the “Import…” link in the action pane to import the correct certificate.

clip_image010[5]

Posted On Thursday, October 22, 2015 1:24 PM | Comments (0) | Filed Under [ General Build Guides Deployment ]

Tuesday, October 20, 2015

Office 365: Authentication

When we’re talking authentication the first thing that pops up in our minds is Active Directory. For years, active directory has been the staple identity provider for most companies and the foundational building block upon which most applications were built.

With Azure and O365, we need to think about the different authentication methods that could be. Are we going to an “all in the cloud” model? Federated identities? Hybrid active directory? Or maybe something else completely?

All in the Microsoft cloud

With the first possible solution we’re looking at an identity solution where nothing exists on premise. The most unlikely solution for the larger businesses, but if you’re a small or new business, this might be an option. You’re still in charge and you can still do, pretty much, the same things when it comes to authentication, but you’re hosting all your user information in the cloud with no servers on-prem.

clip_image002

1 - From the identity and authentication in office 2013 and O365 document

clip_image004

clip_image006

2 - From the Identity and authentication in office 2013 and O365 document

clip_image008

Living in a hybrid world

Most of the world does not live in an all Microsoft cloud only world. Companies have existing infrastructure, applications that need time to be ported and so much more items that restrict them from doing away with existing on-prem servers (and thank god for that or we would be out of a job!) that living in a hybrid world is necessary. But what does that look like?

Same-sign on

Behind door number one is the same-sign on option. Minimal on-prem infrastructure (a dirsync server is required) allows companies to leverage the “same sign-on” method. Historically the DirSync server would not sync end users password but we have that possibility now. OK, before anyone freaks out, let me clarify: Password Sync does not synchronize the password. It has no way of doing that. What it actually does is take the hash of the users password that exists in active directory, hashes that again, and syncs it up to Azure Active Directory. That way, Users can be authenticated using the same password they have in their on-prem active directory. But they will have to authenticate again. It is not single sign-on!

And yes, that’s a hash of a password hash. Hashception… (I really had to do that!)

Single sign-on

Single sign-on is what Microsoft preaches, but does require some extra infrastructure. For a start, you will need at least one ADFS server in order to authenticate against. Ideally you would have multiple so there is redundancy and you don’t lose your authentication infrastructure due to patching.

Authenticating against an ADFS server also means that users don’t need to re-enter their credentials when they are already logged in. Hence the name “Single Sign-On”.

Authentication flow with ADFS for an intranet user

clip_image010

1. An intranet user tries to access an application on Office 365, but hasn’t been authenticated before

2. The application redirects the user to Azure AD for authentication.

3. The user enters the username for the application and, because Azure AD knows ADFS has been set up, redirects that user to the ADFS server for authentication.

4. Since this is a Single sign-on scenario, and the user is working on a desktop which is domain-joined, ADFS issues a user token.

5. User token gets sent to the Intranet User.

6. The User token gets sent to Azure Active Directory, is validated and generates a new token for the application the user is trying to access.

7. The user can happily use the application.

Authentication flow with ADFS for an extranet user

clip_image012

1. Our extranet user tries to access the application for the very first time.

2. The application issues a redirect to Azure AD.

3. Once the redirect is processed, the user enters his or her credentials in the webpage. Azure AD, knowing the organization has ADFS enabled, issues a redirect to the ADFS server.

4. As the user is using the internet (Extranet) to access the ADFS server they hit the ADFS Proxy server which proxies all traffic to the ADFS server living in the internal network. Just like with the Intranet user the ADFS server issues a token.

5. The token gets sent to the user.

6. The token is passed on to Azure Active Directory, validated, a new token is created and passed down to the user.

7. The token is then used to authenticate against the application and the user can start working with vigor!

References:

  • Identity and authentication in Office 2013 and O365
    http://www.microsoft.com/en-us/download/details.aspx?id=38193

Posted On Tuesday, October 20, 2015 3:43 PM | Comments (0) | Filed Under [ Exchange Office 365 ]

Powered by: