2012/12/31

Get-LocalGroupMembership (Using ADSI/WinNT)

Updated (2013/06/03): I added some error handeling/verbose/testing. You are now able to pass multiple computers to the ComputerName parameter.

Intro

Recently I had to do an Audit at my work to find who was Local Administrators on a bunch of Servers.
That might sounds easy when you just have to check 2 or 3 servers... but what if you have to get the information for hundreds! Plus ... I know the Auditor would ask me this same question every few months to prove that the list did not change...Arghhh!

Once again PowerShell saved me so much time on that one!!

Get-LocalGroupMembership

Get the specified local group membership on a local or remote computer.
By default, if you don't specify any parameter, It will query the local group "Administrators" on the localhost.

For some reason WMI bug with some of my Windows Server 2003 and does not return some Domain Groups where Windows Server 2008/2012 work just fine.

Here is my ADSI/WinNT version, It fixed my problem.
In the next post I will go a bit further and get the membership from the domain groups ;-)

Running the Function


The Code

Function Get-LocalGroupMembership {
<#
.Synopsis
    Get the local group membership.
            
.Description
    Get the local group membership.
            
.Parameter ComputerName
    Name of the Computer to get group members. Default is "localhost".
            
.Parameter GroupName
    Name of the GroupName to get members from. Default is "Administrators".
            
.Example
    Get-LocalGroupMembership
    Description
    -----------
    Get the Administrators group membership for the localhost
            
.Example
    Get-LocalGroupMembership -ComputerName SERVER01 -GroupName "Remote Desktop Users"
    Description
    -----------
    Get the membership for the the group "Remote Desktop Users" on the computer SERVER01

.Example
    Get-LocalGroupMembership -ComputerName SERVER01,SERVER02 -GroupName "Administrators"
    Description
    -----------
    Get the membership for the the group "Administrators" on the computers SERVER01 and SERVER02

.OUTPUTS
    PSCustomObject
            
.INPUTS
    Array
            
.Link
    N/A
        
.Notes
    NAME:      Get-LocalGroupMembership
    AUTHOR:    Francois-Xavier Cat
    WEBSITE:   www.LazyWinAdmin.com
#>

 
 [Cmdletbinding()]

 PARAM (
        [alias('DnsHostName','__SERVER','Computer','IPAddress')]
  [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
  [string[]]$ComputerName = $env:COMPUTERNAME,
  
  [string]$GroupName = "Administrators"

  )
    BEGIN{
    }#BEGIN BLOCK

    PROCESS{
        foreach ($Computer in $ComputerName){
            TRY{
                $Everything_is_OK = $true

                # Testing the connection
                Write-Verbose -Message "$Computer - Testing connection..."
                Test-Connection -ComputerName $Computer -Count 1 -ErrorAction Stop |Out-Null
                     
                # Get the members for the group and computer specified
                Write-Verbose -Message "$Computer - Querying..."
             $Group = [ADSI]"WinNT://$Computer/$GroupName,group"
             $Members = @($group.psbase.Invoke("Members"))
            }#TRY
            CATCH{
                $Everything_is_OK = $false
                Write-Warning -Message "Something went wrong on $Computer"
                Write-Verbose -Message "Error on $Computer"
                }#Catch
        
            IF($Everything_is_OK){
             # Format the Output
                Write-Verbose -Message "$Computer - Formatting Data"
             $members | ForEach-Object {
              $name = $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)
              $class = $_.GetType().InvokeMember("Class", 'GetProperty', $null, $_, $null)
              $path = $_.GetType().InvokeMember("ADsPath", 'GetProperty', $null, $_, $null)
  
              # Find out if this is a local or domain object
              if ($path -like "*/$Computer/*"){
               $Type = "Local"
               }
              else {$Type = "Domain"
              }

              $Details = "" | Select-Object ComputerName,Account,Class,Group,Path,Type
              $Details.ComputerName = $Computer
              $Details.Account = $name
              $Details.Class = $class
                    $Details.Group = $GroupName
              $details.Path = $path
              $details.Type = $type
  
              # Show the Output
                    $Details
             }
            }#IF(Everything_is_OK)
        }#Foreach
    }#PROCESS BLOCK

    END{Write-Verbose -Message "Script Done"}#END BLOCK
}#Function Get-LocalGroupMembership


Thanks for Reading! If you have any questions, leave a comment or send me an email at fxcat@lazywinadmin.com. I invite you to follow me on Twitter: @lazywinadm

2012/12/29

Move Computers Object between two organizational units (OU) - What are the permissions required ?

Today I was playing a bit in my lab with PowerShell and AD Computer Objects.
I automate the daily cleanup of Inactive Computer Object and move them to a specific OU.
This script is running with his own service account, the privileges required are specified below.

Move Computer Object INSIDE an OU:
-Create Computer

Move Computer Object OUTSIDE an OU:
-Delete Computer
-Write All Properties

As an example, here I was using the "Delegation of Control Wizard" to allow the "Move out"





2012/12/09

FreeNas 8.3 - Creating a RAID volume and Configure iSCSI

FreeNAS is a tiny Open Source FreeBSD-based operating system which provides free Network-Attached Storage (NAS) services (CIFS, FTP, NFS, ...). It supports sharing across Windows, Apple, and UNIX-like systems.

FreeNAS 8 includes ZFS, which supports high storage capacities and integrates file systems and volume management into a single piece of software.



Overview

In the following post I will cover the following points:
  • Introduction
  • Terminology
  • Raid Volume Configuration
    • Connecting to the FreeNas HTTP Interface
    • Creating the RAID Volume
  • iSCSI Configuration
    • Adding a Portal
    • Adding an Initiator
    • Adding a Target
    • Adding a File Extent
    • Adding a Target / Extent association
    • Enabling the iSCSI Service
  • Configuring the iSCSI Initiator on VMware vSphere 5.1


Introduction

Using FreeNAS 8.3, I need to create a RAID Volume, configure iSCSI and present it to my VMware VSphere 5.1 environment.

Note: If you are not familiar with some of the iSCSI terms used below (target, initiator, extent...) please check the following webpage: http://doc.freenas.org/index.php/ISCSI


Overview of my iSCSI Lab Architecture

2012/12/07

My Home Lab !

I finally ordered my home lab to work on my technical knowledge and to help me work on some certifications. 

My first goal will be to pass my VCP5-DV in February 2013 (It is already booked!) and probably work on some other certifications like Hyper-V, SCCM, W2012...

Here is the configuration I choose

My HomeLab will run on 3 Whiteboxes:
-2 HYPERVISOR  running VMware ESXi VSphere 5.1
-1 STORAGE SERVER running FreeNas 8.3




HYPERVISORS (2 New Whiteboxes)


STORAGE
For this box I took my old HTPC and replaced some components.


More detail on HomeLab page....

2012/11/01

Create a bunch of DNS Entries using PowerShell and DNScmd.exe

Today I needed to create approx. ~50 DNS A entries.
Each of those also need to have a PTR entry.

Lazy as i am... a quick search for PowerShell DNS module did return some interesting things but none who can create both A and PTR DNS entries at the same time.

So I decided to finally use DNSCMD.exe (full syntax on technet) with powershell.

Requirement: DNSCmd.exe is part of the DNS Server Tools and need to be installed prior to use it. On Windows server you can install it using Add-WindowsFeature RSAT-ADDS-Tools


Here is a quick syntax overview of the Dnscmd.exe that we will be using.

dnscmd.exe <DNSServer> /RecordAdd <DNSZone> <NewEntryName> /CreatePTR A <IPAddress>


First Step: Create a CSV with all the information (in Excel or via PowerShell)
here is an example, save it as DNSEntries.csv (in my case at the root of the C: drive)


Second Step: The Script OneLiner:
Import-CSV -Path "c:\DNSEntries.csv" | ForEach-Object { dnscmd.exe $_.dnsserver /RecordAdd $_.zone $_.name /createPTR $_.type $_.IP }


The output should look like this

2012/09/22

PowerShell Resources - From Noob to Ninja

Videos
Windows PowerShell for Beginners
Technet ScriptCenter - Windows PowerShell: Learn It Now Before It's an Emergency

Build2011 - Windows networking with PowerShell: A foundation for data center management
TechEd 2011 - Advanced Automation Using Windows PowerShell 2.0
TechEd 2011 - Windows PowerShell Remoting: Definitely NOT Just for Servers
TechEd 2012 - Windows PowerShell Crash Course
TechEd 2012 - Advanced Automation Using Windows PowerShell 3.0
TechEd 2012 - The Dirty Dozen: Windows PowerShell Scripts for the Busy DBA
TechEd 2012 - Inside Windows Server 2012 Multi-Server Management Capabilities
TechEd 2012 - Group Policy Reporting and Analysis with Windows PowerShell
Technet Radio - The Scripting Guy’s Top 5 PowerShell 3.0 Tips and Tricks
More videos on http://channel9.msdn.com

Guides
Windows PowerShell Survival Guide (en-US) Extensive list of resources on PowerShell
Windows PowerShell 3.0 and Server Manager Quick Reference Guides
Ravikanth Chaganti - WMI Query Language via PowerShell
Don Jones - Secrets of PowerShell Remoting
Windows PowerShell Core About Topics



Code repository
PoshCode
Technet Gallery - Script Repository

Powershell sites
http://technet.microsoft.com/en-us/scriptcenter/powershell.aspx
http://www.powershell.org
http://powershell.com/cs/
http://www.powershellmagazine.com
http://www.powershellpro.com
http://technet.microsoft.com/en-us/scriptcenter/powershell.aspx

2012/09/19

I'm Going to PowerShellSummit !!! @pshsummit

Seattle here I come !!!
I cannot wait to meet all my fellow PowerShell enthousiasts !

The PowerShell Summit will be held at Microsoft in Redmond April 22-24, 2013. Check here for details.