Create Shares on Remote Servers

12 12 2011

Here is a script that will connect to a list of servers, create a folder structure and then create a share on a folder. 

###########################################################################
#
# NAME: Create Share on Remote Servers
#
# AUTHOR:  Brady Randolph
#
# COMMENT:
#
# VERSION HISTORY:
# 1.0 12/8/2011 – Initial release
#
###########################################################################
##    Gather list of server names
$utlservrs = Get-Content c:\admin\utl_servers.txt

##    Loop through each server
foreach ($s in $utlservrs) {
   
    ##    Create folder structure
    if (Test-Path -Path "\\$s\d$\admin") { "Admin folder exists"
    New-Item -ItemType directory "\\$s\d$\admin\DAGFileShareWitness"
    }
    else {"Admin folder doesn’t exist"
    New-Item -ItemType directory "\\$s\d$\admin\"
    New-Item -ItemType directory "\\$s\d$\admin\DAGFileShareWitness"
    }
##    Create folder share   
"Creating Share"   
$cshare = [WMIClass]"\\$s\root\cimv2:Win32_Share"
$result = $cshare.create("D:\admin\DAGFileShareWitness","DAGFileShareWitness",0,25,"DAG File Share Witness")
"Return Result: $result.ReturnValue"

"Adding Exchange Trusted Subsystem group to local admins"
    $Domain = ‘mydomain.corp’
    $ADGroup = ‘Exchange Trusted Subsystem’
    ([ADSI]"WinNT://$s/Administrators,group").add("WinNT://$Domain/$ADGroup,group")
}





Token Bloating

5 10 2011

Here is an article that explains what token bloating is and how to avoid it within your AD environment.  What this article doesn’t explain is the equation to calculate your token size and that is SIZE = 1200 + 40d + 8s where d = domain local groups and s = global and universal groups.

http://www.itadmintools.com/2011/09/avoiding-token-bloat-in-your-active.html

If your environment is already experiencing this issue, here is an article that explains how to increase your token size within AD.

http://support.microsoft.com/kb/327825





Collect Page File Server Configurations

29 09 2011

A client asked me to write a script to gather the page file configurations for ever server in their domain.  At first thought, I was like this will be a piece of cake.  I can use Win32_PageFile WMI class but the class has been deprecated. At second glance, not that difficult just some understanding of the differences between each OS (2008 R2 and 2000) and which WMI classes to use. 

First let’s start with server 2008.  There is the default configuration to “Automatically manage paging file size for all drives.”  This is not available in server 2003 or 2000 and can be found in Win32_ComputerSystem under AutomaticManagedPagefile.  If this is set to true, paging is automatically managed by the OS and the WMI class Win32_PageFileSetting is never created within the OS. 

image

If it is set to false, you can query Win32_PageFileSetting and gather information from that class which includes initial and max page file sizes.

On server 2003, “Automatically manage page file sizes for all drives” isn’t an option so Win32_PageFileSetting is always available. 

Here are a few links to articles I used:

http://www.planetmps.com/Essentials/Properties/CIMV2/ms_409/Win32/Win32_ComputerSystem.html

http://msdn.microsoft.com/en-us/library/aa394245(v=VS.85).aspx

http://msdn.microsoft.com/en-us/library/aa394246(v=VS.85).aspx

http://msdn.microsoft.com/en-us/library/aa394243(v=VS.85).aspx

The script queries AD and loops through a list of servers and exports data to an Excel document.

##################################################################################
##    This script is used to query every server for their page file configs       
##    1. Connect to the domain using ADSI                                            
##  2. Opens Excel, Add a workbook and deletes default workbooks 2 and 3       
##  3. Builds Array of Values to display in header                                
##  4. Creates Excel Header                                                       
##    5. Loop through each server                                                   
##    6. Collect data on each server                                               
##  7. Exports array to Excel                                                   
##  8. Autofit Excel columns                                                   
##  9. Get Time and Date                                                       
##  10. Save Workbook                                                           
##    Script written by Brady Randolph of RBA Consulting 9/29/2011               
##################################################################################

##  1. Connect to the domain using ADSI
$objDomain = [adsi] (“LDAP://OU=Servers,OU=Company,dc=domain,dc=corp”)
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.PageSize = 1000
$objSearcher.Filter = ‘(objectClass=Computer)’
$colResults = $objSearcher.FindAll()

##  2. Opens Excel, Add a workbook and deletes default workbooks 2 and 3
    $excel = new-object -comobject excel.application
    $excel.visible = $true
    $workbook = $excel.workbooks.add()
    $workbook.WorkSheets.item(3).delete()
    $workbook.WorkSheets.item(2).delete()
    #Names the worksheet
    $workbook.WorkSheets.item(1).Name = "Servers"
    $sheet = $workbook.WorkSheets.Item("Servers")

    $lineStyle = "microsoft.office.interop.excel.xlLineStyle" -as [type]
    $colorIndex = "microsoft.office.interop.excel.xlColorIndex" -as [type]
    $borderWeight = "microsoft.office.interop.excel.xlBorderWeight" -as [type]
    $chartType = "microsoft.office.interop.excel.xlChartType" -as [type]
   
    ##  3. Builds Array of Values to display in header
    $Borders = @("Server","Pagefile Location","Automanaged","Pagefile Size","RAM Size","PF Initial Size","PF Max Size","System Drive Free Space","Data Drive Free Space")
    $b = 1
   
    ##  4. Creates Excel Header
    Foreach ($item in $Borders) {
        $sheet.cells.item(1,$b).interior.ColorIndex = 1
        $sheet.cells.item(1,$b).font.bold = $true
        $sheet.cells.item(1,$b).font.colorindex = 2
        $sheet.cells.item(1,$b).borders.LineStyle = $lineStyle::xlContinuous
        $sheet.cells.item(1,$b).borders.ColorIndex = $colorIndex::xlColorIndexAutomatic
        #$sheet.cells.item(1,$b).borders.Weight = $borderWeight::xlMedium
        $sheet.cells.item(1,$b) = $item
        $b = $b + 1
    }
    $x = 2
   
##    5. Loop through each server
foreach ($i in $colResults){
    # Set variables to null
    $Server = $null;$PageFileLocation = $null;$SystemManaged = $null;$PageFileSize = $null;$physicalmem = $null;$SysDriveFreeSpace = $null;$DDriveFreeSpace = $null;
    $PFInitial = $null;$PFMax = $null;
    # Set server name to a string
    [string]$server = $i.properties.name
    $OS_Ver = $i.Properties.operatingsystem
    If (($OS_Ver -like "*server*") -and (Test-Connection -ComputerName $server -Count ’2′)){
        $os = get-wmiobject Win32_OperatingSystem -ComputerName $server
        # Verify if server is 2008 R2 because AutomaticManagedPagefile isn’t an property 2000 and 2003
        if ($os.Version -like "6.1*")  {
            $SystemManaged  = Get-WmiObject -ComputerName $server -Class Win32_ComputerSystem | % {$_.AutomaticManagedPagefile}
            if ($SystemManaged -eq "True"){
           
            ##  6. Collect data on each server
                $physicalmem = gwmi -computer $server Win32_ComputerSystem | % {[Math]::round($_.TotalPhysicalMemory/1MB,0)}
                #$SystemManaged  = Get-WmiObject -ComputerName $server -Class Win32_ComputerSystem | % {$_.AutomaticManagedPagefile}
                $PF = gwmi -computer $server Win32_PageFileUsage
                $PageFileLocation = $PF.Name; $PageFileSize = $PF.AllocatedBaseSize
                $LogicalDrives = Get-WmiObject Win32_logicaldisk -ComputerName $server -Filter "DriveType=’3′"
                    Foreach ($drive in $LogicalDrives) {
                        If ($drive.DeviceID -eq ‘c:’){$SysDriveFreeSpace = [Math]::round($drive.FreeSpace / 1GB,0)}
                        elseif ($drive.DeviceID -eq ‘d:’){$DDriveFreeSpace = [Math]::round($drive.FreeSpace / 1GB,0)}
                        elseif ($drive.DeviceID -eq ‘s:’){$SysDriveFreeSpace = [Math]::round($drive.FreeSpace / 1GB,0)}
                        elseif ($drive.DeviceID -eq ‘t:’){$DDriveFreeSpace = [Math]::round($drive.FreeSpace / 1GB,0)}
                    }
                   
                $values = @($Server,$PageFileLocation,$SystemManaged,$PageFileSize,$physicalmem,$PFInitial,$PFMax,$SysDriveFreeSpace,$DDriveFreeSpace)
                            $y = 1
                           
                            ##  7. Exports array to Excel
                            foreach ($val in $values) {
                                #Add Values to row x and column y
                                $sheet.cells.item($x,$y) = $val
                                #increase column by 1
                                $y = $y + 1}
            }
            else{
           
            ##  6. Collect data on each server
                $physicalmem = gwmi -computer $server Win32_ComputerSystem | % {[Math]::round($_.TotalPhysicalMemory/1MB,0)}
                #$SystemManaged  = Get-WmiObject -ComputerName $server -Class Win32_ComputerSystem | % {$_.AutomaticManagedPagefile}
                $PF = gwmi -computer $server Win32_PageFileUsage
                $PageFileLocation = $PF.Name; $PageFileSize = $PF.AllocatedBaseSize
                $LogicalDrives = Get-WmiObject Win32_logicaldisk -ComputerName $server -Filter "DriveType=’3′"
                    Foreach ($drive in $LogicalDrives) {
                        If ($drive.DeviceID -eq ‘c:’){$SysDriveFreeSpace = [Math]::round($drive.FreeSpace / 1GB,0)}
                        elseif ($drive.DeviceID -eq ‘d:’){$DDriveFreeSpace = [Math]::round($drive.FreeSpace / 1GB,0)}
                        elseif ($drive.DeviceID -eq ‘s:’){$SysDriveFreeSpace = [Math]::round($drive.FreeSpace / 1GB,0)}
                        elseif ($drive.DeviceID -eq ‘t:’){$DDriveFreeSpace = [Math]::round($drive.FreeSpace / 1GB,0)}
                    }
                $PageFileSetting = Get-WmiObject Win32_PageFileSetting -ComputerName $server
                $PFInitial = $PageFileSetting.InitialSize; $PFMax = $PageFileSetting.MaximumSize
                $values = @($Server,$PageFileLocation,$SystemManaged,$PageFileSize,$physicalmem,$PFInitial,$PFMax,$SysDriveFreeSpace,$DDriveFreeSpace)
                            $y = 1   
                           
                            ##  7. Exports array to Excel
                            foreach ($val in $values) {
                                #Add Values to row x and column y
                                $sheet.cells.item($x,$y) = $val
                                #increase column by 1
                                $y = $y + 1}
            }
           
            $x = $x + 1
        }
        Else{
       
        ##  6. Collect data on each server
            $physicalmem = gwmi -computer $server Win32_ComputerSystem | % {[Math]::round($_.TotalPhysicalMemory/1MB,0)}
            #$SystemManaged  = Get-WmiObject -ComputerName $server -Class Win32_ComputerSystem | % {$_.AutomaticManagedPagefile}
            $PF = gwmi -computer $server Win32_PageFileUsage
            $PageFileLocation = $PF.Name; $PageFileSize = $PF.AllocatedBaseSize
            $LogicalDrives = Get-WmiObject Win32_logicaldisk -ComputerName $server -Filter "DriveType=’3′"
                Foreach ($drive in $LogicalDrives) {
                    If ($drive.DeviceID -eq ‘c:’){$SysDriveFreeSpace = [Math]::round($drive.FreeSpace / 1GB,0)}
                    elseif ($drive.DeviceID -eq ‘d:’){$DDriveFreeSpace = [Math]::round($drive.FreeSpace / 1GB,0)}
                    elseif ($drive.DeviceID -eq ‘s:’){$SysDriveFreeSpace = [Math]::round($drive.FreeSpace / 1GB,0)}
                    elseif ($drive.DeviceID -eq ‘t:’){$DDriveFreeSpace = [Math]::round($drive.FreeSpace / 1GB,0)}
                }
            $PageFileSetting = Get-WmiObject Win32_PageFileSetting -ComputerName $server
            $PFInitial = $PageFileSetting.InitialSize; $PFMax = $PageFileSetting.MaximumSize
            $values = @($Server,$PageFileLocation,$SystemManaged,$PageFileSize,$physicalmem,$PFInitial,$PFMax,$SysDriveFreeSpace,$DDriveFreeSpace)
                        $y = 1   
                       
                        ##  7. Exports array to Excel
                        foreach ($val in $values) {
                            #Add Values to row x and column y
                            $sheet.cells.item($x,$y) = $val
                            #increase column by 1
                            $y = $y + 1}
            $x = $x + 1
            }
    }
}
## 8.  Autofit Excel columns
$range = $sheet.usedRange
$range.EntireColumn.AutoFit() | out-null

##  9. Get Time and Date
$date = Get-Date -Format "yyyyMMd"
$time = Get-Date -Format "HHms"

##  10. Save Workbook
$strPath = "c:\temp\ServerPageFiles-$date-$time.xls"
$excel.ActiveWorkbook.SaveAs($strPath)
$excel.quit()
spps -n excel





Add Domain Groups to Server Administrators Local Group

27 09 2011

A client of mine wanted to implement AGDLP, Microsoft’s security framework for granting users and groups rights to servers.  This meant I needed to create a domain local group for each server and add that group to the local administrators group.  This script takes a list of servers, creates a domain local group and adds the group to the server local admins.

##################################################################################
##    This script will create a domain local group and add the group to a servers   
##    local administrators group                                                   
##    1. Set Variables                                                            
##  2. Gather list of servers                                                   
##  3. Connect to OU                                                           
##  4. Loop through each server                                                    
##  5. Create group name                                                       
##  6. Create group                                                               
##  7. Create sAMAccountName                                                   
##  8. Set Description                                                           
##  9. Set group security descriptor                                           
##  10. Complete group addition                                                   
##  11. Add group to server local administrators group                           
##    Script written by Brady Randolph of RBA Consulting 9/27/2011               
##################################################################################

## 1. Set your variables
$DLSecDescriptor = ‘-2147483644′
$Domain = ‘Domain.corp’
$objOU = ‘LDAP://OU=Domain Local,OU=Security,OU=Groups,OU=Company,DC=domain,DC=corp’

## 2. Gather list of servers
$List = Get-Content -Path c:\temp\servers.txt

## 3. Connect to OU
$objDomain = New-Object System.DirectoryServices.DirectoryEntry $objOU

if ($List -ne "") {
   
    ## 4. Loop through each server
    foreach ($Comp in $List) {
        ## 5. Create group name
        $DomainLocalGroup = "DL_" + $Comp + "_Local_Admins"
        ## 6. Create group
        $objGroup = $objDomain.Create("group","CN=" + $DomainLocalGroup)
        ## 7. Create sAMAccountName
        $objGroup.Put("sAMAccountName", $DomainLocalGroup)
        ## 8. Set Description
        $objGroup.Put("Description","Nested in Local Administrators on $Comp")
        ## 9. Set group security descriptor
        $objGroup.Put("groupType", $DLSecDescriptor )
        ## 10. Complete group addition
        $objGroup.SetInfo()
       
        ## 11. Add group to server local administrators group
        ([ADSI]"WinNT://$Comp/Administrators,group").add("WinNT://$Domain/$DomainLocalGroup,group")
    }
}





Gather Members of Administrators group on Servers in Active Directory

27 09 2011

##########################################################
##    This script is used to query every servers "local administrators" members
##    1. Set Variables                                                            
##  2. Query all servers within Active Directory                               
##  3. Loop through each server                                                    
##  4. Gather every member of the Administrators group                           
##    5. Add those values to an array                                               
##    6. Export array to a CSV                                                   
##    Script written by Brady Randolph of RBA Consulting 9/27/2011               
##########################################################

#1. Set Variables
$output = ‘c:\temp\ServersLocalAdmins.csv’
## Sets Global Variable for $Now to eliminate repeatable Get-Date queries
$Global:Now = Set-PSBreakpoint -Variable Now -Mode Read -Action {Set-Variable Now (Get-Date) -Option ReadOnly, AllScope -Scope Global -Force}

#2. Connect to the domain using ADSI
$objDomain = [adsi] ("LDAP://OU=Servers,dc=domain,dc=corp")
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.PageSize = 1000
$objSearcher.Filter = ‘(objectClass=Computer)’
$colResults = $objSearcher.FindAll()
# Creates an empty array
$results = @()

#3. Loop through each server
foreach ($Computer in $colResults) {
    [string]$CompName = $Computer.Properties.name
    #$CompName = $Computer
    $OS_Ver = $Computer.Properties.operatingsystem
    #$OS_Ver = Get-WmiObject -ComputerName $CompName -Class Win32_OperatingSystem | Select-Object {$_.caption}
    #Setting Members to null so values aren’t carried over to next computer
    $members = $null
    If ($OS_Ver -like "*server*"){
        If (Test-Connection -ComputerName $CompName -Count ’2′){
        Out-Host -InputObject "$Now $CompName is Online"
         $group =[ADSI]"WinNT://$CompName/Administrators"
        #4. Gather every member of the Administrators group
        $members = $group.Members() | foreach {$_.GetType().InvokeMember("Name", ‘GetProperty’, $null, $_, $null) }
        #$localmembers | foreach {$_.GetType().InvokeMember("AdsPath","GetProperty",$null,$_,$null)}
        #5. Add those values to an array
        $results += New-Object PsObject -Property @{
        Server = $CompName
        Members = $members -join ";"}
       
          }
   
      Else { Write-Host "$Now $CompName is Offline"}
    }
}
#6. Export array to a CSV
$results | Export-Csv $Output -NoTypeInformation





Displaying Balloon Tip using PoSH

27 09 2011

Let’s assume your script wants to share status information via a balloon message in the system tray area. Here is a sample:

[system.Reflection.Assembly]::LoadWithPartialName(‘System.Windows.Forms’) | Out-Null

$balloon = New-Object System.Windows.Forms.NotifyIcon

$path = Get-Process -id $pid | Select-Object -ExpandProperty Path

$icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)

$balloon.Icon = $icon

$balloon.BalloonTipIcon = ‘Info’

$balloon.BalloonTipText = ‘Completed Operation’

$balloon.BalloonTipTitle = ‘Done’

$balloon.Visible = $true

$balloon.ShowBalloonTip(10000)

 

Note that the code uses the icon of your PowerShell application inside the tray area so the user can associate the message with the application that produced it.

I received this code from PowerShell.com’s PowerTip of the Day.





Calculate IOPS

22 09 2011

Here is a good article explaining how to calculate IOPS for a single disk or arrays.

http://www.techrepublic.com/blog/datacenter/calculate-iops-in-a-storage-array/2182





Clean your TEMP folder

21 09 2011

When disk space gets low, you may want to clean up your temporary folder. The code deletes all files that are older than 30 days to make sure you’re not dumping anything that’s still needed:

$cutoff = (Get-Date) – (New-TimeSpan -Days 30)

 

$before = (Get-ChildItem $env:temp | Measure-Object Length -Sum).Sum

 

Get-ChildItem $env:temp |                           

  Where-Object { $_.Length -ne $null } |            

  Where-Object { $_.LastWriteTime -lt $cutoff } |   

  Remove-Item -Force -ErrorAction SilentlyContinue -WhatIf  # REMOVE -whatif to ENABLE DELETING!

 

$after = (Get-ChildItem $env:temp | Measure-Object Length -Sum).Sum

 

‘Freed {0:0.00} MB disk space’ -f (($before-$after)/1MB)

 

Since deleting stuff is always risky, we left a -WhatIf in the code so you can check that you are actually deleting your temp folder and not anything else (due to a typo for example). Once you are comfortable, remove –WhatIf to invoke the cleanup process. You may be surprised how much garbage can be removed.

Thanks to PowerShell.com for providing this script.





Resync NTP time to local DC

16 09 2011

A client of mine was having an issue because originally within their server build, they were hard coding the NTP server into the registry.  Well that NTP server has now gone away and they wanted to use Active Directories model of using the DC within their site configuration to pull the time from.  Here is a script I used to stop w32time service, reregister w32tm, start w32time service and resync with AD.  This worked great and the client was happy.

net stop w32time
w32tm /unregister
w32tm /register
net start w32time
w32tm /resync





Server 8 Minasi Newsletter

14 09 2011

Here is Mark Minasi’s latest Tech Page regarding Server 8 and the technologies built into Microsoft’s latest server class OS.

http://www.minasi.com/newsletters/nws1109.htm








Follow

Get every new post delivered to your Inbox.