mardi 5 août 2014

"The licensing mode for the Remote Desktop Session Host server is not configured" and Cannot find the Remote Desktop Session Host Configuration tool in Windows Server 2012R2 ?

Dude, the Remote Desktop Session Host Configuration tool no longer exists in Windows Server 2012 :-p

But you still have to configure the licensing mode. You can dot it with GPO through Active Directory.

You can also do it via a local policy.

-->

Run > gpedit.msc

Computer Configuration>Administrative Templates>Windows Components>Remote Desktop Services>Remote Desktop Session Host







vendredi 11 juillet 2014

Add or remove permissions on directory with Powershell

Hi,

If you have to add or remove lot of permissions on different directories, it could be a pain.

But not with Powershell :-)

I write several functions to easily do it.

function Remove-Inheritance($folderPath) {
    $isProtected = $true
    $preserveInheritance = $true
   
    $oFS = New-Object IO.DirectoryInfo($folderPath)
    $DirectorySecurity = $oFS.GetAccessControl([System.Security.AccessControl.AccessControlSections]::Access)
   
    $DirectorySecurity.SetAccessRuleProtection($isProtected, $preserveInheritance)
   
    $oFS.SetAccessControl($DirectorySecurity)
}

function Remove-NTFSPermissions($folderPath, $accountToRemove, $permissionToRemove) {
    $fileSystemRights = [System.Security.AccessControl.FileSystemRights]$permissionToRemove
    $inheritanceFlag = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit"
    $propagationFlag = [System.Security.AccessControl.PropagationFlags]"None"
    $accessControlType =[System.Security.AccessControl.AccessControlType]::Allow

    $ntAccount = New-Object System.Security.Principal.NTAccount($accountToRemove)
    if($ntAccount.IsValidTargetType([Security.Principal.SecurityIdentifier])) {
        $FileSystemAccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($ntAccount, $fileSystemRights, $inheritanceFlag, $propagationFlag, $accessControlType)
       
        $oFS = New-Object IO.DirectoryInfo($folderPath)
        $DirectorySecurity = $oFS.GetAccessControl([System.Security.AccessControl.AccessControlSections]::Access)
       
        $DirectorySecurity.RemoveAccessRuleAll($FileSystemAccessRule)
       
        $oFS.SetAccessControl($DirectorySecurity)
       
        return "Permissions " + $permissionToRemove + " Removed on " + $folderPath + " folder"
    }
    return 0
}

function Add-NTFSPermissions($folderPath, $accountToAdd, $permissionToAdd) {
    $fileSystemRights = [System.Security.AccessControl.FileSystemRights]$permissionToAdd
    $inheritanceFlag = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit"
    $propagationFlag = [System.Security.AccessControl.PropagationFlags]"None"
    $accessControlType =[System.Security.AccessControl.AccessControlType]::Allow

    $ntAccount = New-Object System.Security.Principal.NTAccount($accountToAdd)
    if($ntAccount.IsValidTargetType([Security.Principal.SecurityIdentifier])) {
        $FileSystemAccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($ntAccount, $fileSystemRights, $inheritanceFlag, $propagationFlag, $accessControlType)
       
        $oFS = New-Object IO.DirectoryInfo($folderPath)
        $DirectorySecurity = $oFS.GetAccessControl([System.Security.AccessControl.AccessControlSections]::Access)
       
        $DirectorySecurity.AddAccessRule($FileSystemAccessRule)
       
        $oFS.SetAccessControl($DirectorySecurity)
       
        return "Permissions " + $permissionToAdd + " Added on " + $folderPath + " folder for " + $accountToAdd
    }
    return 0
}


Usage examples :


$folders = "\\server\c$\TestDirectory"

##Remove Inheritance from Top Folder and Child Objects
Foreach($folder in $folders) {
    Remove-Inheritance $folder
    Remove-NTFSPermissions $folder "Authenticated Users" "Read,Modify"
    Remove-NTFSPermissions $folder "Creator owner" "Read,Modify"
    Get-ChildItem -Path $folder -Recurse | ?{$_.PSisContainer} `
    | foreach {
        $subfolder = $_.FullName
        Remove-Inheritance $subfolder
        Remove-NTFSPermissions $subfolder "Authenticated Users" "Read,Modify"
        Remove-NTFSPermissions $subfolder "Creator owner" "Read,Modify"
        Add-NTFSPermissions $subfolder "Authenticated Users" "Read,Modify"       
      }
}








Get remote information of a server in Powershell ("Computer Name","Operating System","Manufacturer","Model","RAM","CPU","IPV4","diskData") Get-ADComputerDetails

Hi !

Your manager wants to know informations about servers joined to the company's Active Directory and you want to retrieve informations with Powerhsell ?

Let's get started !

This script will retrieve servers informations in a CSV file like this :

"Computer Name","Operating System","Manufacturer","Model","RAM","CPU","IPV4","diskData"
"VirtualServer","Windows Server 2008 R2 Standard","VMware, Inc.","VMware Virtual Platform","8 GB","2","10.193.17.42","C: 14.47 GB / 39.9 GB - D: 23.48 GB / 100 GB"
"PhysicalServer","Windows Server 2008 R2 Standard","IBM","IBM System x3550 M4 Server -[***43*G]-","32 GB","1","10.193.17.217","C: 33.36 GB / 100 GB - D: 373.54 GB / 456.61 GB"

$ADComputerProperties = @(`
"Operatingsystem",
"OperatingSystemServicePack",
"Created",
"Enabled",
"LastLogonDate",
"IPv4Address",
"CanonicalName"
)

$SelectADComputerProperties = @(`
"Name",
"OperatingSystem",
"OperatingSystemServicePack",
"Created",
"Enabled",
"LastLogonDate",
"IPv4Address",
"CanonicalName"
)

$servers = Get-ADComputer -Filter * -SearchBase "ou=servers,ou=IT resources,DC=ad,DC=dieteren,DC=be" -Properties $ADComputerProperties | select $SelectADComputerProperties
Foreach ($server in $servers)
{
    $hostName = $server.Name
    $operatingSystem = $server.OperatingSystem
    $serverInfo = (Get-WmiObject -Computername $hostName Win32_ComputerSystem)
    $manufacturer = $serverInfo.Manufacturer
    $model = $serverInfo.Model
    $displayGB = [math]::round($serverInfo.TotalPhysicalMemory/1024/1024/1024, 0)
    $ipv4 = $server.IPv4Address
    $serverDiskInfo = (Get-WmiObject -Computername $server.Name win32_logicaldisk -Filter "drivetype='3'")

    $cpu = @(Get-WmiObject -Class Win32_processor -Computername $hostName)
    $c_socket = $cpu.count
    $c_core = $cpu[0].NumberOfCores * $c_socket
    $c_logical = $cpu[0].NumberOfLogicalProcessors * $c_socket
  
    $psobject = New-Object -TypeName psObject -Property ([ordered]@{
        'Computer Name' = $hostName
        'Operating System' = $operatingSystem
        'Manufacturer' = $manufacturer
        'Model' = $model
        'RAM' = "$displayGB GB"
        'CPU' = $c_socket
        'IPV4' = $ipv4
    })

    $psobject | Add-Member -type NoteProperty -name diskData -Value NotSet
   
    $i=0
    Foreach ($disk in $serverDiskInfo) {       
        $diskSize = [math]::Round($disk.size / 1gb,2)
        $diskFreeSpace = [math]::Round($disk.freespace / gb,2)                               
        Write-Host "$($disk.deviceid) $diskFreeSpace GB / $diskSize GB"      
        if($i -eq 0) {
            $psobject.diskData = "$($disk.deviceid) $diskFreeSpace GB / $diskSize GB"
        }
        else {
            $psobject.diskData += " - $($disk.deviceid) $diskFreeSpace GB / $diskSize GB"
        }
        $i++
    }     
    
   
    $psobject | Export-Csv C:\ComputerDetails.csv -Append 
}



lundi 16 juin 2014

Microsoft DFS-R problem : The sysvol permissions for one or more GPOs on this domain controller are not in sync with the permissions for the GPOs on the baseline domain

Hello,
Recently, I encountered a Distributed File System Replication problem in our Active Directory.
Notice : pay attention that the AD replication and Sysvol replication are two very different things. Indeed, the replication of Sysvol is done wit DFS mechanism which replaced FRS since 2008.
In windows 2012r2, through the new Group Policy Management, when I click on "Detect Now", results show ACLs not in sync with the baseline domain...



The sysvol permissions for one or more GPOs on this domain controller are not in sync with the permissions for the GPOs on the baseline domain

First thing, the level of the domain and forest functionnal level is 2008r2.

I check first the DFS Replication with tools provided by Microsoft in the DFS Management Console on the baseline DC (Health Report, Propagation test et Propagation report). The result was ok...
You can use dfsrdiag to check DFS-R operations.
dfsrdiag.exe syncnow /rgname:“domain system volume” /partner:yourBaselineDC /time:1 /verbose

Steps to solve the problem :

1. DNS check on all DCs (the first DNS server must be the DC itself)
2. Resume replication on volume c:\ on the baseline DC
Get the volumeGuid
GWMI -namespace root\cimv2 -class win32_volume | FL -property DriveLetter, DeviceID
Resume replication on volume
wmic /namespace:\\root\microsoftdfs path dfsrVolumeConfig where 'volumeGuid="ce3fb9d1-6ecf-447e-b99c-6e451cab8012"' call ResumeReplication
3. Force the authoritative synchronisation for the DFSR-replicated SYSVOL (was the "D4" when we used FRS in the past) from the PDC Emulator (http://support.microsoft.com/kb/2218556)
a)
Get-ADObject "CN=SYSVOL Subscription,CN=Domain System Volume,CN=DFSR-LocalSettings,CN=YourPDCEmulation,OU=Domain Controllers,DC=domain,DC=com" -properties * 
b) 
Set-ADObject "CN=SYSVOL Subscription,CN=Domain System Volume,CN=DFSR-LocalSettings,CN=YourPDCEmulation,OU=Domain Controllers,DC=domain,DC=com" -Replace @{"msDFSR-Enabled"="FALSE";"msDFSR-Options"=1} 
c) On all other DCs
Set-ADObject "CN=SYSVOL Subscription,CN=Domain System Volume,CN=DFSR-LocalSettings,CN=DCx,OU=Domain Controllers,domain,DC=com" -Replace @{"msDFSR-Enabled"="FALSE"} 
d) repadmin /syncall /AdeP
e) Start of the DFSR service on the PDC Emulator.
f) On the PDC Emulator :
Set-ADObject "CN=SYSVOL Subscription,CN=Domain System Volume,CN=DFSR-LocalSettings,CN=YourPDCEmulation,OU=Domain Controllers,DC=domain,DC=com" -Replace @{"msDFSR-Enabled"="TRUE"} 
g) repadmin /syncall /AdeP
h) From the PDC Emulator in an elevated command prompt : DFSRDIAG POLLAD
i)  Start of the DFSR service on all other DCs
j) On all other DCs  :
Set-ADObject "CN=SYSVOL Subscription,CN=Domain System Volume,CN=DFSR-LocalSettings,CN=DCx,OU=Domain Controllers,domain,DC=com" -Replace @{"msDFSR-Enabled"="TRUE"} 
k) On all other non-authoritative DCs  in an elevated command prompt : DFSRDIAG POLLAD
4) Then reset permissions of all listed GPOs 
In Group Policy Management Console, click on a GPO>delegation tab>Advanced>Advanced>Restore Defaults (or make a script to restore defaults permissions and to keep custom permissions.


Note :

Remember that it's recommended to edit your GPOs from the PDC Emulator. The PDC Emulator is the prefered admistration entry point for services like GPOs and DFS.

When using Remote Server Administration Tools, you can choose the domain controlter to use.

In Administrative Users and Computers console>right click on your domain>change domain controller



Then choose the DC to use. 










mardi 22 avril 2014

VMWare/Powershell - Get Virtual Machine CPU/RAM/Disk/Network usage reports minute by minute and without aggregation of time units

Hi !

The initial goal here is to measure the Virtual machines activity hosted on a ESXi infrastructure. We want to measure activity with an interval of one minute during a period of 24 hours.

The major problem is that Veeam One (tool we use to monitor our virtualized infrastructure), makes aggregation of time units to restrict the size of database and to accelerate reports and graphs generation.

Veeam One, despite the configuration performed at the VMWare hypervisor itself, these rules apply:
  • Raw data (data with 20-second resolution) is stored for 1 hour.
  • After 1 hour, raw data is aggregated to 5-minute resolution data.
  • After 1 week, data with 5-minute resolution is aggregated to 2-hour resolution data. Data with this level of detail is stored in the database for up to 1 year.

We opened a Veeam online ticket to determine with them if there was a possibility to change this behavior and respond well to our needs. Here is the central point of their response:
  • Veeam One Reporter is not able to send out reports with the discression of 1 minute
  • Veeam One Monitor does not send out reports

Bad news :-(

Let's go to script ^^

First sterp, download VMware vSphere PowerCLI: 


Ok, let's load the snap-in which allow us to use the VMWare cmdlets to automate tasks and managementof virtualized infrastructure:
Add-PSSnapin VMware.VimAutomation.Core

Connect to VCenter server :
Connect-VIServer –Server VotreServeurVcenter

Retrieve, for example, CPU values in %, minute by minute, for yesterday :
$statCPU = Get-Stat -Entity $vmToQuery -Stat cpu.usage.average -Start $start -Finish $stop | where{$_.Instance -eq ""}

The simplest way: 
$statCPU = Get-Stat -Entity $vmToQuery -CPU -Start $start -Finish $stop | where{$_.Instance -eq ""}

We get an array with the CPU values in %, minute by minute according to the specified interval.

For example, yesterday with a 24h period, you can use:
$start = (Get-Date -Hour 0 -Minute 0 -Second 0).AddDays(-1)
$stop = (Get-Date -Hour 23 -Minute 59 -Second 0).AddDays(-1)

The first idea is to use this array to generate an Excel file with values in % and timestamp. The second idea is to generate a graph plotting the curves according to the data.

To make these graphs, we can use the great .net 3.5 (or higher) framework : 
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization")

Create the chart and the chartarea :
$chart = new-object System.Windows.Forms.DataVisualization.Charting.Chart
$chartarea = new-object system.windows.forms.datavisualization.charting.chartarea

Give appropriate dimensions:
$chart.width = 1500
$chart.Height = 600
$chart.Left = 40
$chart.top = 30

Manage the title:
$titlefont=new-object system.drawing.font("ARIAL",12,[system.drawing.fontstyle]::bold)
$title =New-Object System.Windows.Forms.DataVisualization.Charting.title
$chart.titles.add($title)
$chart.titles[0].text = "CPU/Ram - " + $vmToQuery + " (" + $reportDate + ")"
$chart.titles[0].font = $titlefont
$chart.titles[0].forecolor = "Black"
$chart.Name = $vmToQuery
$chart.BackColor = [System.Drawing.Color]::White

A little bit of colors :-) (Never hesitate to look at the complete list here: http://msdn.microsoft.com/fr-fr/library/system.drawing.color_properties(v=vs.90).aspx) :
$chartarea.BackColor = [System.Drawing.Color]::FloralWhite

Ok, add the chartarea to your chart: 
$chart.ChartAreas.Add($chartarea)

$legend = New-Object system.Windows.Forms.DataVisualization.Charting.Legend
$chart.Legends.Add($legend)

Add the vertical legend of the X-axis with a 15 minutes interval (each point represents one minute)
$chartarea.AxisX.LabelStyle.Angle = -90
$chartarea.AxisX.Interval = 15 

Following lines allow to make a series with a data type and thus if we want, manage different traces on the same graph:
$chart.Series.Add("CPU")
$chart.Series["CPU"].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Line
$chart.Series["CPU"].color = "blue"

Go through the array, and add each value to a psobject (http://msdn.microsoft.com/en-us/library/system.management.automation.psobject(v=vs.85).aspx)  

Then, we cast our timestamp and we add our points to the chart series "CPU" ($chart.Series["CPU"].Points.AddXY($dtToString, $t.Value)):

 foreach($t in $statCPU) {  
    $out = new-object psobject

    $out | Add-Member noteproperty timeStampCPU $t.Timestamp
    $out | Add-Member noteproperty valueCPU $t.Value
   
    $dtToString = $t.Timestamp
    [string]$dtToString = $dtToString -f "hh:mm"

    $chart.Series["CPU"].Points.AddXY($dtToString, $t.Value)

    $result += $out   

$chartarea.AxisY.Title = $unitCPU

$filename = $logFolder + "\" + $vmToQuery + "_" + $reportDate + ".png"
$chart.SaveImage($filename, "PNG")

CSV export (parameter –append needs Powershell v3.0) :
$result | Export-CSV -path $logFile –append –NoTypeInformation  

I consolidated the CPU and RAM usage information on the same graph to finally get this:


Same things for Network and Disk usage:

$statRAM = Get-Stat -Entity $vmToQuery -Stat mem.usage.average -Start $start -Finish $stop
$statNetwork = Get-Stat -Entity $vmToQuery -Network -Start $start -Finish $stop
$statDisk = Get-Stat -Entity $vmToQuery -Disk -Start $start -Finish $stop  

You can get this result:






Have fun :-)