Locking your Workstation with PowerShell

locking-your-workstation

Locking a workstation using PowerShell?  It sounds like an easy task, right?  That’s what I thought too…and told the customer…but NO!  Friends, it wasn’t easy…before now.

As it turns out, some tasks in Windows just aren’t accessible via WMI.  For instance, the useful Win32_OperatingSystem class has some nifty methods for working with the system’s power state, like Reboot and Shutdown…but strangely none for locking the system!

01

Then I stumbled upon this useful post by Ed over at The Scripting Guys, but this was back in the dark ages of VBScript, and unfortunately the only answer they found was to use Rundll32.exe to call a method in a dll and that, frankly will not fly.  You’ll hear the shrillest high and lowest lows over the radio, and my voice will guide you home, they will see us waving from such great heights–

Sorry, that phrase is still a trigger word for me and takes me back to my deeply embarrassing emo phase…moving right along.

How to work with native methods easily in PowerShell

If you want to know how this is done…stop right here and read this awesome blog post by Danny Tuppenny on the topic.  It’s eye-wateringly in-depth.  But if you just want an example of how it is done, lets proceed.

Now, we all know by now that we can use Add-Type to work with native C# code…but the brilliant thing that Danny did is create a function which just makes it very easy to import a dll and get at the methods within…then surface those methods as a new class.  It’s the bomb.com.

# Helper functions for building the class
$script:nativeMethods = @();
function Register-NativeMethod([string]$dll, [string]$methodSignature)
{
    $script:nativeMethods += [PSCustomObject]@{ Dll = $dll; Signature = $methodSignature; }
}
function Add-NativeMethods()
{
    $nativeMethodsCode = $script:nativeMethods | % { "
        [DllImport(`"$($_.Dll)`")]
        public static extern $($_.Signature);
    " }

    Add-Type @"
        using System;
        using System.Runtime.InteropServices;
        public static class NativeMethods {
            $nativeMethodsCode
        }
"@
}

With that done, we’ll now have some a function available to us, Register-NativeMethod. To use this, we simply provide the name of the .dll we want to use, and then what’s known as the method signature. For instance, let’s say I wanted to use User32.dll to move a window, as described here. Here’s the method signature for that method.

BOOL WINAPI MoveWindow(
  _In_ HWND hWnd,
  _In_ int  X,
  _In_ int  Y,
  _In_ int  nWidth,
  _In_ int  nHeight,
  _In_ BOOL bRepaint
);

The hWnd is kind of a special variable, it means HandlerWindow, or MainWindowHandle. You can get a MainWindowHandle by running Get-Process Name | select MainWindowHandle. All of the other values are just integeres, so that would be the window position in X and Y and the width and height. Finally, you can provide a true, false value with bRepaint (but I didn’t bother).

We can implement this in PowerShell by using the Register-NativeMethod function, like so:

Register-NativeMethod "user32.dll" "bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight)"

Finally, we call it like so:

#Find the first Notepad process' MainWindowHandle
$Handle = Get-Process notepad | select -first 1 -expand MainWindowHandle
[NativeMethods]::MoveWindow($Handle, 40, 80, 400, 400)

And here’s how it looks in practice.

gif

If you’d like to know what other Methods are available, you can turn to the lovely Pinvoke website which has a listing of every method available from all of these dlls.  And you can just plug and play them all, easily!

Particularly of note are methods in user32.dll and kernel32.dll, but deep-linking doesn’t work, so you’ll have to click the dll name on the left column.

But what about locking the WorkStation?

I didn’t forget about you!  To lock the workstation, run

Register-NativeMethod "user32.dll" "bool LockWorkStation()"

#Calling the method to lock it up
[NativeMethods]::LockWorkStation()

Complete Code

# Helper functions for building the class
$script:nativeMethods = @();
function Register-NativeMethod([string]$dll, [string]$methodSignature)
{
    $script:nativeMethods += [PSCustomObject]@{ Dll = $dll; Signature = $methodSignature; }
}
function Add-NativeMethods()
{
    $nativeMethodsCode = $script:nativeMethods | % { "
        [DllImport(`"$($_.Dll)`")]
        public static extern $($_.Signature);
    " }

    Add-Type @"
        using System;
        using System.Runtime.InteropServices;
        public static class NativeMethods {
            $nativeMethodsCode
        }
"@
}


# Add methods here

Register-NativeMethod "user32.dll" "bool LockWorkStation()"
Register-NativeMethod "user32.dll" "bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight)"
# This builds the class and registers them (you can only do this one-per-session, as the type cannot be unloaded?)
Add-NativeMethods

#Calling the method
[NativeMethods]::LockWorkStation()
Advertisements

Hands-off deployments

 

handsoff

Let’s face it, guys.  There are times that you JUST don’t have access to SCCM, MDT or Kace, and need to deploy a completely automated and silent Windows install without our normal build tools.  If this is you, and you deploy systems frequently, you’ve probably spent way too much time looking at screens like this one

wicd-1

Not only does it stink to have to type a user name and password every time, it also slows you down. Admit it, whenever you start a Windows install, you start doing something else, and then an hour later check back and have to reload the whole task in your memory again.  It’s a giant waste of time and makes you less productive.

To top it off, there are probably things you always do, like setup user accounts, join a machine to a domain, and set the time zones (we can’t all live in the chosen timezone of Pacific Standard Time).

Previously, making these changes and baking them in to an unattended install meant using the terrible Windows SIM tool, which was horrible.  Seriously, no offense meant, but if you had a hand in designing the System Image Manager tool, I’m sure you’re already ashamed.  Good, you should be.

Thankfully we now have the Windows Image Configuration Designer (Wicd) which makes this all super easy!

In this post, we’ll walk you through everything you need to do to make a fully silent, unattended Windows Install, along with some useful settings too.  We will be installing WICD, which is part of the ADK, and then walk through configuring the following settings:

  • ‘Enable Remote Desktop out of the box’

  • Set Default Time zone (no west coast time!)

  • Set Default First User

  • Silent Install (depends on setting a user account)

  • Make the computer do a quick virus scan on first boot

  • Optional – Domain Join

  • Optional – Add files to the image

  • Optional – Make Registry Changes on the Image

Setting up WICD

To get access to the awesome WICD tool, you’ll need to have the Windows 10 ADK.  I recommend using version 1607, at a minimum (Download Link).  When installing the ADK make sure to check the two red boxes shown below, for full features.

wicd-2
If you leave these unchecked, it won’t be WICD good.  Make sure to ☑️

Continue reading

Class is in Session: PowerShell Classes

ClassesInPowerShellGraphic

PowerShell has been mostly complete for you and me, the ops guys, for a while now. But for Developers, important features were missing.

One of those features were Classes, a important development concept which probably feels a bit foreign to a lot of my readers. For me, I’d been struggling with classes for a long time. Ever since Middle School. #DadJokeLol.

In this post, I’ll cover my own journey from WhatIsGoingOnDog to ‘Huh, I might have something that resembles a clue now’.

I’ll cover what Classes are, why you might want to use them, and finally show a real-world example.

What the heck are Classes?

If you’ve been scripting for a while, you’re probably very accustomed to making CustomObjects. For instance, I make Objects ALL the file that contain a subset of properties from a file. I’ll commonly select a File’s Name, convert it’s size into KB, and then display the LastWriteTime in days. Continue reading

SCCM v Intune Showdown

sccm

If you’re an SCCM Administrator you’ve likely heard of InTune and might be wondering when to use it.

In this post, we’ll cover how SCCM and Intune are able to manage Windows 10 full desktop computers (including laptops and Windows tablets like the Surface or Surface book.)

If instead you’re wondering about managing the Surface RT, lol, enjoy your metro cutting board.

Best use for a Surface RT in 2016

To understand where InTune really shines, let’s think of where SCCM works best:

  • known and defined network infrastructure
  • well connected end-point devices (less of an issue today)
  • standardized hardware models
  • standardized, company owned hardware
  • Active Directory Domain (all SCCM servers must be domain members)
  • Managed machines are either domain joined, or need certificates (certs =PKI =Even more infrastructure and configuration)
  • Wonderfully powerful imaging capabilities

It becomes pretty obvious, SCCM is for the big enterprise,  which its also expensive and has some serious requirements.

Now, let’s contrast this to the management story we have from Intune:

  • No requirement for local hardware or infrastructure
  • No on premises Active Directory requirement
  • Works very well with Azure AD
  • Works great with user owned and heterogeneous devices
  • Literally zero imaging options

For the rest of this post, I’ll list the big capabilities of an Enterprise Client Management tool and contrast how each of these tools perform at that task, we’ll cover: Continue reading

Microsoft Ignite 2016 : Recap

Last week, I was able to attend my first big IT Conference, a dream of mine since I first got into IT almost ten years ago.  I got to attend Microsoft Ignite!

IT WAS AWESOME!

In this post, I’ll recap some of my experiences attending…and being able to speak there as well!

On the value of Ignite

Ignite is Microsoft’s gigantic combination of TechEd and MMS, a far-reaching summit covering all of Microsoft’s technology stack, from devices to SQL, asp.net to Azure, everything is here.

It is HUGE. Just overwhelmingly big. You simply cannot attend every session, and you’ll probably find yourself triple or quadruple booked for sessions.  Keep in mind that conferences like Ignite commonly take place in massive convention centers like the Georgia World Congress Center.  Actually, while I’m talking about it:

The GWCC

The Georgia World Congress Center is absolutely unfathomably big.  It is the fourth biggest convention center in the United States.  If you’re in Hall A, the walk to Hall C will easily take you twenty minutes or more.  And the session might be full by the time that you get there. Continue reading