Navigation

Entries by Carlos Perez (157)

Wednesday
Mar282012

Introduction to Microsoft PowerShell– Basics of Running Cmdlets

PowerShell Cmdlets

You will notice that for the PowerShell commands I use the word Cmdlet, that is how Microsoft calls and spells the word. In a PowerShell shell you can execute regular windows commands in addition to the cmdlets and most work without any problem some may experience problems depending on the parameters used since PowerShell uses space as a delimiter so do keep this in mind when you are running local exe files.

PowerShell cmdlets are in the form of a <verb>-<noun>, you will see common verbs like set, get, clear, write and stop to name a few and each belong to a group of actions, you can get an updated list of verbs at the TechNet site http://social.technet.microsoft.com/wiki/contents/articles/4537.powershell-approved-verbs-en-us.aspx do keep this list handy because if you create any module, cmdlet or function you should follow the naming so as to not confuse users and not get warnings from PowerShell when loading modules or cmdlets. To get a list of cmdlets on PS we use the Get-Command cmdlet:

image 

  When ran with no options we get a list of all cmdlet, functions and Aliases we have available. Just like on a Unix shell you will notice you have functions and aliases at your disposal to call. Aliases are mainly for saving time when entering commands and to make others more familiar when ran in a shell like the ls or the cat commands:

PS C:\Users\Carlos Perez> ls
    Directory: C:\Users\Carlos Perez
Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d-r--         2/16/2012   3:03 PM            Contacts
d-r--         3/26/2012  11:23 PM            Desktop
d-r--         2/16/2012   3:03 PM            Documents
d-r--          3/8/2012   3:52 PM            Downloads
d-r--         2/16/2012   3:03 PM            Favorites
d-r--         2/16/2012   3:03 PM            Links
d-r--         2/16/2012   3:03 PM            Music
d-r--         2/16/2012   3:03 PM            Pictures
d-r--         2/16/2012   3:03 PM            Saved Games
d-r--         2/16/2012   3:03 PM            Searches
d-r--         2/16/2012   3:03 PM            Videos
-a---         3/28/2012   8:16 PM         28 hello.txt
PS C:\Users\Carlos Perez> cat .\hello.txt
hello world
PS C:\Users\Carlos Perez> rm .\hello.txt
PS C:\Users\Carlos Perez> ls
    Directory: C:\Users\Carlos Perez
Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d-r--         2/16/2012   3:03 PM            Contacts
d-r--         3/26/2012  11:23 PM            Desktop
d-r--         2/16/2012   3:03 PM            Documents
d-r--          3/8/2012   3:52 PM            Downloads
d-r--         2/16/2012   3:03 PM            Favorites
d-r--         2/16/2012   3:03 PM            Links
d-r--         2/16/2012   3:03 PM            Music
d-r--         2/16/2012   3:03 PM            Pictures
d-r--         2/16/2012   3:03 PM            Saved Games
d-r--         2/16/2012   3:03 PM            Searches
d-r--         2/16/2012   3:03 PM            Videos

As we can see the aliases makes the shell behave similar to a Unix/Linux shell, but do keep in mind it is only similar, the parameters are not the same. 

One can use the tab key to auto complete PSDrive Paths (More on this on another blog post), File Paths,  Functions, Cmdlets, Function Options, Cmdlets Parameters, Variables and regular Windows Commands. So one can so Get-<tab> and keep hitting tab to cycle through the cmdlets available with the verb Get, the same can be done to find a cmdlet parameter like Get-Service –<tab>

The Get-Command also allow us to filter using wildcards:

PS C:\Users\Carlos Perez> Get-Command -Name *service* -CommandType cmdlet
CommandType     Name                                                Definition
-----------     ----                                                ----------
Cmdlet          Get-Service                                         Get-Service [[-Name] <String[]>] [-ComputerName ...
Cmdlet          New-Service                                         New-Service [-Name] <String> [-BinaryPathName] <...
Cmdlet          New-WebServiceProxy                                 New-WebServiceProxy [-Uri] <Uri> [[-Class] <Stri...
Cmdlet          Restart-Service                                     Restart-Service [-Name] <String[]> [-Force] [-Pa...
Cmdlet          Resume-Service                                      Resume-Service [-Name] <String[]> [-PassThru] [-...
Cmdlet          Set-Service                                         Set-Service [-Name] <String> [-ComputerName <Str...
Cmdlet          Start-Service                                       Start-Service [-Name] <String[]> [-PassThru] [-I...
Cmdlet          Stop-Service                                        Stop-Service [-Name] <String[]> [-Force] [-PassT...
Cmdlet          Suspend-Service                                     Suspend-Service [-Name] <String[]> [-PassThru] [...

On Windows 8 in PowerShell v3 we have the the Show-Command cmdlet that will bring a GUI Interface for exploring the cmdlet and it options allowing us to copy the command we build or run the command:

image

When we want to get specific help on any cmdlet we can use the get-help cmdlet or it’s alias help:

image

This will provide us with a base help for the cmdlet where we can see:

  • Name
  • Synopsis
  • Syntax
  • Description
  • Related Links
  • Remarks

We can use the –detail option to get more details on the options, their types and position in the command arguments if we pass each value without an option, we can also use the –examples to get example on how to use the cmdlet and a brief description of what the command is doing and we can get a with –full the entire content of the help message. You can consider help/Get-Help as the man command in Unix/Linux. When you look at the Syntax section the options you can quickly determine what values you can provide to them. When we see the message we will see that each optional Parameter we can pass is between [ ], if a parameter is not optional it will not be enclosed in [ ], some options do not require values those are just –<Parametername> other will take a value, for those that take a value PS will let you know the value type if it is a string, integer, object ..etc between <>, some can take a list of values and you will notice those will be in the format of <type[]>  and those that have a predefined list of options that can be given to a parameter will be in the format of < option1 | option2 | option3>.  I highly recommend that when starting with a cmdlet for the first time to use the –full parameter when getting help. The full help message will provide us additional information for each parameter as shown bellow:

 -Name <string[]>
     Specifies the service names of services to be retrieved. Wildcards are permitted. By default, Get-Service gets
     all of the services on the computer.
     Required?                    false
     Position?                    1
     Default value
     Accept pipeline input?       true (ByValue, ByPropertyName)
     Accept wildcard characters?  true
 -RequiredServices [<SwitchParameter>]
     Gets only the services that this service requires.
     This parameter gets the value of the ServicesDependedOn property of the service. By default, Get-Service gets a
     ll services.
     Required?                    false
     Position?                    named
     Default value                False
     Accept pipeline input?       false
     Accept wildcard characters?  false

As it can be seen for the –Name parameter we can see additional information like if it is required or not, the position when calling the cmdlet, this means that the cmdlet will take the first thing given to it an use it as the value for this parameter when the parameter is not given, we can also see it accepts inputs from the pipeline and that this can be a value or a property. In the case of the RequiredServices  parameter the position is named, that means that the name of the parameter must be specified with the value.

If the computer you are running PowerShell on has internet connectivity you can give the parameter–online to the Get-Help cmdlet to open a browser window with the latest help information for it.

Let take a look at the Get-Service cmdlet:  

image

As we can see we in syntax we can call the cmdlet in 3 different ways, one where we start by providing the name or names of the service, another where we provide Display Names and a third where we pass service controller objects (Remember PowerShell cmdlets output objects). Let look at the first one:

Get-Service [[-Name] <string[]>] [-ComputerName <string[]>] [-DependentServices] [-Exclude <string[]>] [-Include <string[]>] [-RequiredServices] [<CommonParameters>]

As we can see the –Name parameter takes a list of strings. Lets get the state of several services:

PS C:\Users\Carlos Perez> Get-Service -Name BITS, VSS
Status   Name               DisplayName
------   ----               -----------
Running  BITS               Background Intelligent Transfer Ser...
Stopped  VSS                Volume Shadow Copy

Now we ask for a full help for the command we will see for the name option that it accepts wildcard characters for the parameter of -Name and for the parameter of –DisplayName  so we can search for any service with the word WMI in its Display Name:

PS C:\Users\Carlos Perez> Get-Service -DisplayName *WMI*
Status   Name               DisplayName
------   ----               -----------
Stopped  wmiApSrv           WMI Performance Adapter

The Wildcard Characters that can be used are shown in the table bellow:

Wildcard Character Description Example

*

Matches zero or more characters, starting at the specified position

a*

?

Matches any character at the specified position

?n

[ ]

Matches a range of characters

[a-l]name

[ ]

Matches the specified characters

[bc]name

 

In PowerShell one can use parameter abbreviation, similar to what one can do with commands on Cisco IOS we only need to enter enough of the parameter name that is is unique against the other. In the Get-Process cmdlet the only parameter that starts with the letter N is Name so we can shorten it to only this letter:

PS C:\Users\Carlos Perez> Get-Process -N *vm*
Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    270      20     8956       7708    87            1392 vmtoolsd
    289      23    15252      14388   145   113.97   2544 vmtoolsd
     68       9     3444       3148    68     0.55   2532 VMwareTray

As we play with parameters and comandlets one of the things we can do is to maintain a transcript. We can do this with the Start-Transcript cmdlet, this will save all of our commands and output to a file and when we issue the cmdlet Stop-Transcript it will stop recording our action, we can even append to an existing file by giving it the –Append parameter. One thing to note is that you can not use it on ISE.

PS C:\Windows\system32> Start-Transcript C:\windows\Temp\testtranscript.txt
Transcript started, output file is C:\windows\Temp\testtranscript.txt
PS C:\Windows\system32> Get-Service | select -first 1
Status   Name               DisplayName
------   ----               -----------
Stopped  AeLookupSvc        Application Experience
PS C:\Windows\system32> Get-process | select -first 1
Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
     23       4     2128       1460    38     0.09    408 cmd
LogName: PS C:\Windows\system32> Stop-Transcript
Transcript stopped, output file is C:\windows\Temp\testtranscript.txt

Now as mentioned before PowerShell cmdlets return objects and we can pipe this objects to other cmdlets. We can illustrate by saving an object in to a variable and looking at what we have available. In PowerShell variables start with with $ In this example we will look at the object for the BITS service:

PS C:\Windows\system32> $srv = Get-Service -Name BITS
PS C:\Windows\system32> $srv
Status   Name               DisplayName
------   ----               -----------
Running  BITS               Background Intelligent Transfer Ser...

If we want to know it’s type we can use the .Net method of gettype()

PS C:\Windows\system32> $srv.GetType().fullname
System.ServiceProcess.ServiceController

If we want to look at the methods (actions that can be taken) and Properties (Information) of an object we can use the Get-Members cmdlet.

PS C:\Windows\system32> Get-Member -InputObject $srv
   TypeName: System.ServiceProcess.ServiceController
Name                      MemberType    Definition
----                      ----------    ----------
Name                      AliasProperty Name = ServiceName
RequiredServices          AliasProperty RequiredServices = ServicesDependedOn
Disposed                  Event         System.EventHandler Disposed(System.Object, System.EventArgs)
Close                     Method        System.Void Close()
Continue                  Method        System.Void Continue()
CreateObjRef              Method        System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)
Dispose                   Method        System.Void Dispose()
Equals                    Method        bool Equals(System.Object obj)
ExecuteCommand            Method        System.Void ExecuteCommand(int command)
GetHashCode               Method        int GetHashCode()
GetLifetimeService        Method        System.Object GetLifetimeService()
GetType                   Method        type GetType()
InitializeLifetimeService Method        System.Object InitializeLifetimeService()
Pause                     Method        System.Void Pause()
Refresh                   Method        System.Void Refresh()
Start                     Method        System.Void Start(), System.Void Start(string[] args)
Stop                      Method        System.Void Stop()
ToString                  Method        string ToString()
WaitForStatus             Method        System.Void WaitForStatus(System.ServiceProcess.ServiceControllerStatus desi...
CanPauseAndContinue       Property      System.Boolean CanPauseAndContinue {get;}
CanShutdown               Property      System.Boolean CanShutdown {get;}
CanStop                   Property      System.Boolean CanStop {get;}
Container                 Property      System.ComponentModel.IContainer Container {get;}
DependentServices         Property      System.ServiceProcess.ServiceController[] DependentServices {get;}
DisplayName               Property      System.String DisplayName {get;set;}
MachineName               Property      System.String MachineName {get;set;}
ServiceHandle             Property      System.Runtime.InteropServices.SafeHandle ServiceHandle {get;}
ServiceName               Property      System.String ServiceName {get;set;}
ServicesDependedOn        Property      System.ServiceProcess.ServiceController[] ServicesDependedOn {get;}
ServiceType               Property      System.ServiceProcess.ServiceType ServiceType {get;}
Site                      Property      System.ComponentModel.ISite Site {get;set;}
Status                    Property      System.ServiceProcess.ServiceControllerStatus Status {get;}

 

We can also pipe the contents of the variable to the the cmdlet like so $srv | Get-Members as we can see we can get information like status, type, dependencies and we can take actions like pause , start and stop. we can also use tab completion to cycle thru the methods and properties of an object when it is in a variable.

Lets stop the service and get it’s status before and after:

PS C:\Windows\system32> (Get-Service -Name BITS).status
Stopped
PS C:\Windows\system32> (Get-Service -Name BITS).start()
PS C:\Windows\system32> (Get-Service -Name BITS).status
Running

You will notice that methods are always called with ( )  in the end since a methods takes parameters, properties we can call directly and they are the state of when the object was created that is why we execute the command and work with the object directly by running the command between parenthesis. 

Also properties and the results from methods can have methods and more properties beneath them, we can chain this to get the value or results we want.

PS C:\Windows\system32> $srv.Status.GetType()
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     ServiceControllerStatus                  System.Enum

Another way would be to use the refresh method:

PS C:\Windows\system32> $srv.Status
Running
PS C:\Windows\system32> $srv.Stop()
PS C:\Windows\system32> $srv.Refresh()
PS C:\Windows\system32> $srv.Status
Stopped

As you can see one of the main advantages of PowerShell is the is the advantage to manipulate the data as objects and not as text. In the next post I will cover more on how to work with several objects, how to modify the objects and piping.

As always I hope you find this post informative and useful.

Tuesday
Mar272012

Introduction to Microsoft PowerShell – What is it and Setup

What Is PowerShell

I do believe that one of the biggest skills that both Administrator and Security Professional should have is to be able to automate tasks on a systems they are responsible for. Many old Unix long bearded veterans say that admins are lazy and they script and automate tasks because of that, I see it as being smart, we are taking tasks that could take hours and crunch it down to seconds, we reduce risk by making sure an action is repeatable and we learn in the process of automating making us better. So I decided to start a series of blog post and do an introduction on one of my favorite scripting languages which is Microsoft PowerShell.

PowerShell as the name implies is a shell first, a scripting language second. Microsoft a long time ago did a study on areas that they considered they where week and needed improvement and one of this was the ability to automate and administer a system thru a shell. Microsoft designed and came with what I consider a rather unique approach in PowerShell and that is a Object Model based shell. Most shells in Linux, Unix and even cmd.exe shell in Windows are text driven where each command returns it’s out put in strings, in PowerShell the output of each command or cmdlet as it is called in PowerShell is a .Net Object that we can then use in many unique ways.  The grammar is based originally on the POSIX Shell grammar and then evolved and expanded by adding concepts from Perl, Python, VBScript and C#.

Setting Up the Environment

Depending our version of Windows are the steps we need to take to get PowerShell running on our system. On Windows system after Windows 7 and Windows Server 2008 R2 power shell comes built in, on Windows 2008 it i s a feature that needs to be installed from the feature available in server manager and on Windows Vista, Windows XP and Windows 2003 you will need to download the installer from the download section in http://www.microsoft.com/powershell and install the package. For this series I will be covering v2.0 of PowerShell and some of the new improvements that will come with v3.0.  One important thing to keep in mind is that PowerShell uses the .Net framework so running the latest version of .Net Framework will provide us the best flexibility and capabilities on the objects returned from the PowerShell commands.

You will notice the depending your platform and build you will have x86 and/or x64 versions of PowerShell console and PowerShell ISE (Interactive Scripting Environment), the shortcuts will be located in Windows XP, Windows 2003 and Windows Vista in  Start –> All Programs –>Windows PowerShell V2 and on more modern versions of Windows you will find it in Start –> All Programs –> Accessories –> Windows PowerShell in addition to this from a command prompt or from the run dialog box you can call powershell.exe for the console and powershell_ise.exe to launch the Integrated Scripting Environment.

The Console

One of the first things you will notice when you launch the console in your machine it will be a console screen with a Blue background and lightly yellow letters

image

I recommend that you customize even more the shortcut by doing a Right Click on the PowerSherll Symbol on the top left and selecting Properties

image

In Options increase Buffer Size so as to save more commands in the buffer and enable QuickEdit Mode and Insert Mode if not selected.

image

Under Layout we can adjust the With and the Height of our Screen Buffer to better accommodate our screen size and the amount of output history we want for scrolling  in the Console.

image

If a program line Exchange Server or VMware PowerCLI sets a separate shortcut for a console for use of their snapping we must also do the changes on those shortcuts also. If you run PowerShell by invoking the command via a command prompt or thru the Run dialog box you will be greeted with a screen like this one:

image

Easily confused with a command prompt and does not have any of the setting we set since those are for the shortcut it self. Since PowerShell is a component at setup none of those settings that come set by default are set because PowerShell reads the information from HKCU\Console for the user. To customize this I recommend you visit this page http://poshcode.org/2220 and copy and paste the PowerShell code shown there and paste it in a PowerShell prompt running as Administrator you can use the Windows Calculator in Scientific mode to set your values in the proper hex values and do the changes in notepad before running the commands. This will give you a console like the one you call from the shortcut in your programs menu. These changes can also be made on Windows 8 running PowerShell v3.

Console Keyboard Commands

Keyboard

Operation

Left/Right Arrow Keys Move the editing cursor one space each time thru the current command line.
Crtl+Left Arrow, Crtl+Right Arrow Keys Moves the editing cursor one word each time thru the current command line
Home Moves cursor to beginning of the current command line
End Moves cursor to the end of the current command line
Up/Down Arrow Keys Moves up and down thru the command history
Tab Does command and option completion
F7 Shows command history window that can be navigated with the Up and Down Arrow Keys, pressing Enter will execute the command selected in the window
Insert Key Toggles between character insertion and character overwrite mode
Delete Key Deletes a character under the editing cursor in the current command line
Backspace Key Deletes a character to the left of the editing cursor in the current command line

In the addition to the history command window one sees when pressing the F7 Key

image

One can use the Get-History cmdlet or the history alias for the command (More details on command and how to use the history command for generating scripts in blog posts to come) he command will return a list of the commands enter indexed with a number:

PS C:\Users\Carlos Perez> get-history
  Id CommandLine
  -- -----------
   1 dir
   2 Get-Process
   3 Get-Service
   4 Get-Command -Verb get
To recall one of the commands in the history one uses the # symbol and the number of the command an the press the tab key to pull the command from history to the current command line. 

 

Integrated Scripting Environment

Microsoft started including with PowerShell 2.0 the ISE (Integrated Scripting Environment) this is more than a script editor it also functions as as interactive shell and support plugins that can extend it’s functionality.

image

Some of the advantages of the ISE are:

  1. Multiple Script editing tabs.
  2. Use of easier editing and selection of command output.
  3. Color Syntax for PowerShell Scripts
  4. Remote PowerShell Session.
  5. Execution of selected PowerShell Code with F8
  6. Tab Completion for Command and Options

Microsoft greatly improved ISE in PowerShell v3 by adding IntelliSense just like in Visual Studio an improve command window that looks and behaves better and a command search pane:

image 

 

Conclusion

I invite you to play with settings for your console and ISE and get it to a point where you are confortable with the setup and appearance and also invite you to play a bit with the commands. In the next blog post we will go a little deeper in to the existing commands, loading modules and snapping, getting help and execution policy for scripts. 

Thursday
Mar222012

Creating WMI Filters and GPOs with PowerShell

In my last 2 blog post I covered the creation of group policy objects for distributing certificates to all computers in a domain and enable Network Level Authentication on them plus also covered how to create and use WMI filters to specify which machines a Group Policy Object should apply to. On this blog post I will cover how to do this with Windows 2008 R2 built in PowerShell Module and some external ones from SDM Software. The GPO that we will be creating is to disable RDP on none Vista, Windows 7 and Windows 2008 hosts since following the other  blog posts these do not support NLA on their Remote Desktop Service. We will use PowerShell on a Windows 2008 R2 Domain Controller. Since we are going to use external scripts we would first start modifying the execution policy this is done by running the Set-ExecutionPolicy command to allow local scripts to execute without the need of being signed.

PS C:\Windows\system32> Set-ExecutionPolicy remotesigned
Execution Policy Change
The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose
you to the security risks described in the about_Execution_Policies help topic. Do you want to change the execution
policy?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"): y
PS C:\Windows\system32>

As stated by the command this could be a potential security risk so do remember to re-run the command at the en with the execution policy of Restricted. Before we start creating group policy objects and linking them we should create a WMI Filter that we will attach to the policy. I took the liberty to write one based on another one I saw in the Microsoft Scripting Repository that will create a series of base filters for you when ran in a Domain Controller running Windows 2008 or Windows 2008 R2. You can download the script from my GitHub account at https://github.com/darkoperator/powershell_scripts/blob/master/create-wmifilters.ps1 the script will make the necessary changes to the registry to allow modification of attributes locally on the box thus allowing us to add the filters. The script is ran from a PoweShell Window providing the path like any other PowerShell script:

PS C:\Users\Administrator\Documents> .\create-wmifilters.ps1
Checking is registry key is set to allow changes to AD System Only Attributes is set.
Allow System Only Change key is not set
Creating key and setting value to 1
Starting creation of WMI Filters:
Adding WMI Filter for: Virtual Machines
Adding WMI Filter for: Workstation 32-bit
Adding WMI Filter for: Workstation 64-bit
Adding WMI Filter for: Workstations
Adding WMI Filter for: Domain Controllers
Adding WMI Filter for: Servers
Adding WMI Filter for: Windows 2000
Adding WMI Filter for: Windows XP
Adding WMI Filter for: Windows Vista
Adding WMI Filter for: Windows 7
Adding WMI Filter for: Windows Server 2003
Adding WMI Filter for: Windows Server 2008
Adding WMI Filter for: Windows Server 2008 R2
Adding WMI Filter for: Windows Vista and Windows Server 2008
Adding WMI Filter for: Windows Server 2003 and Windows Server 2008
Adding WMI Filter for: Windows 2000, XP and 2003
Finished adding WMI Filters
Disabling Allow System Only Change Attributes on server

Now you will have some WMI Filters we can use as base in our Group Policy Objects, do remember that we can have several filters linked to a single GPO.

Once this is done we can import the GroupPolicy PowerShell module that is installed on Windows 2008 Domain Controllers when promoted and look at the available commands we get from the module:

PS C:\> Import-Module grouppolicy
PS C:\> Get-Command -Module grouppolicy | Format-Table -AutoSize
CommandType Name                       Definition
----------- ----                       ----------
Cmdlet      Backup-GPO                 Backup-GPO -Guid <Guid> -Path <String> [-Comment <String>] [-Domain <String>]...
Cmdlet      Copy-GPO                   Copy-GPO -SourceGuid <Guid> -TargetName <String> [-SourceDomain <String>] [-T...
Cmdlet      Get-GPInheritance          Get-GPInheritance [-Target] <String> [-Domain <String>] [-Server <String>] [-...
Cmdlet      Get-GPO                    Get-GPO [-Guid] <Guid> [[-Domain] <String>] [[-Server] <String>] [-All] [-Ver...
Cmdlet      Get-GPOReport              Get-GPOReport [-Guid] <Guid> [-ReportType] <ReportType> [[-Path] <String>] [[...
Cmdlet      Get-GPPermissions          Get-GPPermissions -Guid <Guid> [-TargetName <String>] [-TargetType <Permissio...
Cmdlet      Get-GPPrefRegistryValue    Get-GPPrefRegistryValue -Guid <Guid> -Context <GpoConfiguration> -Key <String...
Cmdlet      Get-GPRegistryValue        Get-GPRegistryValue -Guid <Guid> -Key <String> [-ValueName <String>] [-Domain...
Cmdlet      Get-GPResultantSetOfPolicy Get-GPResultantSetOfPolicy [-Computer <String>] [-User <String>] -ReportType ...
Cmdlet      Get-GPStarterGPO           Get-GPStarterGPO -Guid <Guid> [-Domain <String>] [-Server <String>] [-All] [-...
Cmdlet      Import-GPO                 Import-GPO -BackupId <Guid> -Path <String> [-TargetGuid <Guid>] [-TargetName ...
Cmdlet      New-GPLink                 New-GPLink -Guid <Guid> -Target <String> [-LinkEnabled <EnableLink>] [-Order ...
Cmdlet      New-GPO                    New-GPO [-Name] <String> [-Comment <String>] [-Domain <String>] [-Server <Str...
Cmdlet      New-GPStarterGPO           New-GPStarterGPO [-Name] <String> [-Comment <String>] [-Domain <String>] [-Se...
Cmdlet      Remove-GPLink              Remove-GPLink -Guid <Guid> -Target <String> [-Domain <String>] [-Server <Stri...
Cmdlet      Remove-GPO                 Remove-GPO -Guid <Guid> [-Domain <String>] [-Server <String>] [-KeepLinks] [-...
Cmdlet      Remove-GPPrefRegistryValue Remove-GPPrefRegistryValue [[-Server] <String>] -Guid <Guid> -Context <GpoCon...
Cmdlet      Remove-GPRegistryValue     Remove-GPRegistryValue [-Guid] <Guid> [-Key] <String> [[-ValueName] <String>]...
Cmdlet      Rename-GPO                 Rename-GPO -Guid <Guid> -TargetName <String> [-Domain <String>] [-Server <Str...
Cmdlet      Restore-GPO                Restore-GPO -BackupId <Guid> -Path <String> [-Domain <String>] [-Server <Stri...
Cmdlet      Set-GPInheritance          Set-GPInheritance [-Target] <String> -IsBlocked <BlockInheritance> [-Domain <...
Cmdlet      Set-GPLink                 Set-GPLink -Guid <Guid> -Target <String> [-LinkEnabled <EnableLink>] [-Order ...
Cmdlet      Set-GPPermissions          Set-GPPermissions -Guid <Guid> -PermissionLevel <GPPermissionType> -TargetNam...
Cmdlet      Set-GPPrefRegistryValue    Set-GPPrefRegistryValue -Guid <Guid> -Context <GpoConfiguration> -Key <String...
Cmdlet      Set-GPRegistryValue        Set-GPRegistryValue -Guid <Guid> -Key <String> [-ValueName <String[]>] [-Valu...

We now use the New-GPO comandlet to create a new empty GPO named DisableRDP:

PS C:\> New-GPO -Name "DisableRDP"
DisplayName      : DisableRDP
DomainName       : acme-lab.com
Owner            : ACME-LAB\Domain Admins
Id               : 31122b47-5129-420f-9fe8-241584cc516d
GpoStatus        : AllSettingsEnabled
Description      :
CreationTime     : 3/20/2012 7:56:43 AM
ModificationTime : 3/20/2012 7:56:44 AM
UserVersion      : AD Version: 0, SysVol Version: 0
ComputerVersion  : AD Version: 0, SysVol Version: 0
WmiFilter        :

Now that we have a Group Policy Object created we can use the commadlet to create a registry reference in the GPO that will be applied to the machines that process the GPO under the context of Computer:

PS C:\> Set-GPPrefRegistryValue -Name DisableRDP -Key "HKLM\System\CurrentControlSet\Control\Terminal Server" -ValueName fDenyTSConnections -Value 1 -Type Dword -Context computer -Action update

Now to be able to link a WMI Filter to a GPO we need some external commands provided for free by SDM Software from http://www.sdmsoftware.com/products/freeware/ and we download the SDM GPMC PowerShell Cmdlets and install them on the Domain Controller. Once installed we can load the module:

PS C:\Users\Administrator\Documents> import-module SDM-GPMC

We want to use the Add-SDMWMIFilterLink command to link our GPO with one of the WMI Filters we created for the target of the GPO. To look at examples on how to use it we use the help command with the switch for examples:

PS C:\Users\Administrator\Documents> help Add-SDMWMIFilterLink -Examples
NAME
    Add-SDMWMIFilterLink
SYNOPSIS
    Adds a WMI Filter to a particular GPO
    --------------  Example 1 --------------
    C:\PS>Add-SDMWMIFilterLink "Wireless Policy" -FilterName "Laptop Test"
    Links the WMI filter called "Laptop Test" to the GPO called "Wireless Policy"
    Filter Laptop test linked to GPO Wireless Policy

As we can see the command is quite simple to use we just need to provide it a name for the GPO and a filter name to link to the GPO. Lets link now the GPO with the WMI Filter:

PS C:\Users\Administrator\Documents> Add-SDMWMIFilterLink "DisableRDP" -FilterName "Windows 2000, XP and 2003"
Filter Windows 2000, XP and 2003 linked to GPO DisableRDP

Once done we can now link the GPO to any part of our Active Directory structure. In this case I will attach it to the entire Forest of my lab AD infrastructure:

PS C:\Users\Administrator\Documents> New-GPLink -Name DisableRDP -Target "dc=acme-lab,dc=com”
GpoId       : 31122b47-5129-420f-9fe8-241584cc516d
DisplayName : DisableRDP
Enabled     : True
Enforced    : False
Target      : DC=acme-lab,DC=com
Order       : 3
DisplayName      : DisableRDP
DomainName       : acme-lab.com
Owner            : ACME-LAB\Domain Admins
Id               : 31122b47-5129-420f-9fe8-241584cc516d
GpoStatus        : AllSettingsEnabled
Description      :
CreationTime     : 3/20/2012 7:56:43 AM
ModificationTime : 3/20/2012 8:18:04 AM
UserVersion      : AD Version: 0, SysVol Version: 0
ComputerVersion  : AD Version: 1, SysVol Version: 1
WmiFilter        :
DisplayName      : DisableRDP
DomainName       : acme-lab.com
Owner            : ACME-LAB\Domain Admins
Id               : 31122b47-5129-420f-9fe8-241584cc516d
GpoStatus        : AllSettingsEnabled
Description      :
CreationTime     : 3/20/2012 7:56:43 AM
ModificationTime : 3/20/2012 7:56:44 AM
UserVersion      : AD Version: 0, SysVol Version: 0
ComputerVersion  : AD Version: 0, SysVol Version: 0
WmiFilter        :

This could be a very good way to automate the process of creating Group Policy Objects in lab and then move this to a production environment. Also you could use it for automating disaster recovery procedures.

As always I hope you found this blog post useful and informative.

Monday
Mar192012

WMI Filters in Group Policy Objects

One of the problems that we see every day in production environments is that even when we would like to have all machines on the same version of Windows many times this is not possible so we have to adapt our Group Policies to these environments. Microsoft provides a great way to check several parameters of the box thru Windows Management Instrumentation (WMI), this allows is from checking Hardware, software, patches and many other attributes available via the Windows Management Instrumentation (WMI). Lets say we want the previous Group Policy we created to apply only to Windows 2008 R2, Windows 2008, Vista and Windows 7 and lets also make a filter for Windows XP and 2003 so if we decide to make a filter to apply a policy to only those we can apply the filter. We start by going to the Group Policy  Management Console and choosing under the domain WMI Filters image We now Right Click an select New to create a new filter. We will get a screen where we will enter a name and a description for our first filter that will be for Windows 2008, Windows 2008R2, Windows Vista and Windows 7, the operating systems that support Network Level Authentication (NLA) on Remote Desktop Protocol (RDP). image Now we click on Add on the Queries section so as to add the WMI Query Language query we will use to filter to what Operating systems the policy is applied to: image We will select from Win32_OperatingSystem  the Version, this will give us a version number of 6.0 for Windows Vista and Windows 2008, 6.1 for Windows 2008 R2 and Windows 7. we will use:

SELECT * FROM Win32_OperatingSystem WHERE Version like "6.%"

We would click on Add type our filter and then just click on Ok:

image

We now click on save and the filter is ready to apply.

To apply a filter we just select the policy we want to apply the filter to and select from the WMI Filtering section the WMI Filter we want from the dropdown box:

image

In the case we wanted the filter to be for earlier supported versions of Windows we would use:

SELECT * FROM Win32_OperatingSystem WHERE Version LIKE "5.%"

If we wanted to even go more granular we could create separate filter for Product Type where:


  • ProductType 1 is for Client Versions of Windows
  • ProductType 2 is for Server Version of Windows operating as a Domain Controller
  • ProductType 3 for Server Version of Windows that are not a Domain Controller

If we wanted this to apply to all servers but not domain controller we could do a query like this one:

SELECT * FROM Win32_OperatingSystem WHERE (Version like "5.%" OR Version like "6.%") and ProductType<>2

As you can see there is a lot of flexibility with filters, specially since we can have several of them. As always I hope you find the post informative and useful.

Saturday
Mar172012

Configuring Network Level Authentication for RDP

Recently there has been a lot of attention given to the Remote Desktop Protocol for attacker. The protocol has seen a work in 2011 that abused week passwords and  it’s features to copy files and infect other machines and now in 2012 there is a remote code execution bug in the protocol it self. Since the days of Vista and Windows 2008 Microsoft has provided a new mechanism for securing RDP connections with what they call Network Level Authentication, this uses Microsoft CredSSP Protocol to authenticate and negotiate credential type before handing off the connection to RDP Service.

CredSSP first establishes an encrypted channel between the client and the target server by using Transport Layer Security (TLS). Using the TLS connection as an encrypted channel; it does not rely on the client/server authentication services that are available in TLS but does uses it for validating identity. The CredSSP Protocol then uses the Simple and Protected Generic Security Service Application Program Interface Negotiation Mechanism (SPNEGO) Protocol Extensions to negotiate a Generic Security Services (GSS) mechanism that performs mutual authentication and GSS confidentiality services to securely bind to the TLS channel and encrypt the credentials for the target server. It should be noted that all GSS security tokens are sent over the encrypted TLS channel. This tokens can be NTL, Kerberos or PKI Authentication for SmartCards.

The graphic bellow illustrates how this is done:

 

image

Most brut force tools currently out there do not take in to account NLA, it would slow down the process even more and add another level of complexity. Since no packet will reach the RDP service until CredSSP has finished negotiation of the connection it protects the servers from DoS and exploits.

NLA is present in the latest versions of Windows, for Server:

  • Windows 2008
  • Windows 2008 R2
  • Windows 7
  • Windows Vista

On the client side:

  • Windows XP SP3
  • Windows Vista
  • Windows 7
  • Windows 2008
  • Windows 2008 R2
  • Remote Desktop Connection for Mac

NLA was introduced first with RDP 6.0 in Windows Vista and later on Windows XP SP3.

One of the biggest advantages also is that since TLS is used it will warn us if it can not validate the identity of the host we are connecting to. For this we will need a PKI infrastructure integrated with AD in our Windows environment. On a Windows 2008 environment we can install on a server the role of Active Directory Certificate Service to install a Enterprise CA accepting all defaults so it can provide Computer Certificates to the machines in the domain in an automated way using Group Policy.

Configuring a GPO for NLA

In this example I will show how to configure a GPO for issuing a Certificate to each host in the Domain and Configure NLA authentication for RDP. In a production environment you may wish to separate these or keep them in one policy depending on your AD design.

Lets start by selecting from Administrative Tools the Group Policy Management tool:

image

On the tool we create a New Group Policy Object:

image

We give this policy a Name:

image

Once created we edit this policy by right clicking on it an selecting Edit:

image

Now we select Computer Configuration/Policies/Windows Settings/Public Key Policies/Automatic Certificate Request Settings:

image

We now right click on Automatic Certificate Request Setting and select to create a new Automatic Certificate Request, this will request to the CA a new Computer Certificate and renew the certificate when it expires automatically.

image

When the wizard starts we click Next then we select Computer Certificate Template:

image

We click on Next and then on Finish. Now we select Computer Configuration/Policies/Windows Settings/Public Key Policies under that node we double click on Certificate Services Client – Auto-Enrollment we now select on the properties under Configuration Model we select Enable and make sure that the boxes for managing certificates in the store and for updating the certificate if the template is modified.

image

Now we have finished the section that will cover the certificate assignment for computers that get this GPO applied to.

For configuring RDP to use NLA we now go to Computer Configuration/Policies/Administrative Templates/Windows Components/Remote Desktop Settings/Remote Desktop Session Host/Security

image

Select Require user authentication for remote connections by using Network Level Authentication and double click on it. On the properties screen select Enable and click on OK.

Now lets configure the client settings to make sure that we always select to warn in the case the host certificate con not be authenticated. We select Computer Configuration/Policies/Administrative Templates/Windows Components/Remote Desktop Settings/Remote Desktop Connection Client

We double click on Configure Authentication for Client

image

Select Enable and set the Option to Warn me if authentication fails

image

Click on OK and close the screen. Know you should have a proper policy that cam be applied, but before we apply the policy we have to give permission on the Domain Computers group in the domain the permission to apply it:

image

 

And now we have a GPO that can be linked to any Domain in the forest or Organization Unit. Once applied when a connection is made we can see the security in use by clicking on the lock on the top of a Remote Desktop Session in Windows and it will tell us how we where authenticated:

image

On those host that do not have RDP enabled you will see that the only option available is to use NLA

image

 

As always I hope you find this blog post informative and useful.

Page 1 ... 7 8 9 10 11 ... 32 Next 5 Entries »