www.flickr.com
Posts tonen met het label powershell. Alle posts tonen
Posts tonen met het label powershell. Alle posts tonen

woensdag 19 januari 2011

Active Directory groepslidmaatschappen kopiëren

Waar je in de AD users & computers snap-in wel gebruikers kunt aanmaken aan de hand van een bestaande gebruiker, is dit bij groepen niet mogelijk. Ook hier komt Powershell weer van pas (icm. Quest cmd-lets).

De onderstaande code zorgt ervoor dat de lidmaatschappen van een brongroep worden overgebracht naar een bestemmingsgroep. Als je het helemaal perfect wil hebben, kun je ook nog code toevoegen om de bestemmingsgroep gescript aan te maken. Maar ik vind het zo al prima:

$srcGroup = "source group"
$dstGroup = "destination group"
Get-QADGroupMember "$srcGroup" | foreach {
add-qadgroupmember "$dstGroup" -Member $_
}

woensdag 27 oktober 2010

Expliciete ACLs inventariseren met Powershell

Het is met NTFS erg gemakkelijk om op allerlei niveaus rechten in te stellen. Deze rechten worden meestal ook doorgegeven aan de onderliggende objecten. Om een overzicht te krijgen van objecten waarop expliciet rechten zijn ingesteld, heb ik een klein stukje Powershell code geschreven.

Get-ChildItem -Recurse | %{
$Path = $_.FullName
(Get-Acl $Path).Access | where {$_.IsInherited -eq $false} | Select-Object `
@{n='Path';e={ $Path }}
} | sort-object -property Path -unique

De output van dit script is uiteraard volledig naar wens aan te passen. Wellicht is het ook mogelijk om dit op andere providers toe te passen dan een NTFS filesysteem. Er zijn namelijk ook applicaties zoals MS Exchange en SQL server waarin ACLs worden gebruikt.

dinsdag 26 oktober 2010

SQL 2008 Express backups met PowerShell

Als je gebruikt maakt van de Express editie van SQL Server, dan zul je het moeten doen zonder Maintenance Plans. Hoewel dit een zeer eenvoudige tools is om te gebruiken, is er voor SQL 2008 Express een goed alternatief beschikbaar; PowerShell!

Beter goed gejat dan slecht verzonnen was mijn insteek bij deze oplossing. Ik heb gebruik gemaakt van de volgende artikelen:
Daarnaast had ik zelf een one-liner om bestanden ouder dan een bepaalde tijd op te ruimen. Als je dit combineert, dan krijg je het onderstaande resultaat.

#
# Loads the SQL Server Management Objects (SMO)
#

$ErrorActionPreference = "Stop"

$sqlpsreg="HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.SqlServer.Management.PowerShell.sqlps"

if (Get-ChildItem $sqlpsreg -ErrorAction "SilentlyContinue")
{
throw "SQL Server Provider for Windows PowerShell is not installed."
}
else
{
$item = Get-ItemProperty $sqlpsreg
$sqlpsPath = [System.IO.Path]::GetDirectoryName($item.Path)
}


$assemblylist =
"Microsoft.SqlServer.Management.Common",
"Microsoft.SqlServer.Smo",
"Microsoft.SqlServer.Dmf ",
"Microsoft.SqlServer.Instapi ",
"Microsoft.SqlServer.SqlWmiManagement ",
"Microsoft.SqlServer.ConnectionInfo ",
"Microsoft.SqlServer.SmoExtended ",
"Microsoft.SqlServer.SqlTDiagM ",
"Microsoft.SqlServer.SString ",
"Microsoft.SqlServer.Management.RegisteredServers ",
"Microsoft.SqlServer.Management.Sdk.Sfc ",
"Microsoft.SqlServer.SqlEnum ",
"Microsoft.SqlServer.RegSvrEnum ",
"Microsoft.SqlServer.WmiEnum ",
"Microsoft.SqlServer.ServiceBrokerEnum ",
"Microsoft.SqlServer.ConnectionInfoExtended ",
"Microsoft.SqlServer.Management.Collector ",
"Microsoft.SqlServer.Management.CollectorEnum",
"Microsoft.SqlServer.Management.Dac",
"Microsoft.SqlServer.Management.DacEnum",
"Microsoft.SqlServer.Management.Utility"


foreach ($asm in $assemblylist)
{
$asm = [Reflection.Assembly]::LoadWithPartialName($asm)
}

Push-Location
cd $sqlpsPath
update-FormatData -prependpath SQLProvider.Format.ps1xml
Pop-Location

$s = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "(local)"

$Date = Get-Date
$bkdir = $s.Settings.BackupDirectory
$dbs = $s.Databases
foreach ($db in $dbs)
{
if($db.Name -ne "tempdb") #We don't want to backup the tempdb database
{
$dbname = $db.Name
$dt = get-date $Date -format yyyyMMddHHmm #We use this to create a file name based on the timestamp
$dbBackup = new-object ("Microsoft.SqlServer.Management.Smo.Backup")
$dbBackup.Action = "Database"
$dbBackup.Database = $dbname
$dbBackup.Devices.AddDevice($bkdir + "\" + $dbname + "_" + $dt + ".bak", "File")
$dbBackup.Initialize = $true
$dbBackup.SqlBackup($s)
}
}
$CutOff = 7
$bkdir | get-childitem | where {$_.PSIsContainer -eq $false -AND $_.LastWriteTime.date -lt ($Date).AddDays(-$CutOff)} | Remove-Item

woensdag 20 oktober 2010

PowerCLI als vervanger voor COS opdrachten - ESX patches

Met de release van vSphere versie 4.1 was het hoge woord eruit. De volgende 'major' release van vSphere zal uitsluitend in een ESXi variant beschikbaar komen.

Deze gedachte speelt al een tijdje in mijn achterhoofd als ik het beheer van ESX servers uitvoer. Vaak maak ik gebruik van een batchfile die door middel van plink, pageant en public/private keypairs commando's uitvoert in het Console Operating System (service console) van een groep ESX servers.

Dit is zometeen dus niet meer mogelijk en zodoende probeer ik tegenwoordig zoveel mogelijk met PowerCLI te doen. Een van de opdrachten die ik probeer om te zetten is het opvragen van geïnstalleerde software. Dit is van belang omdat ik de versie van een geïnstaleerde netwerk driver wil kunnen zien.

Helaas is er geen PowerCLI versie van het RPM commando beschikbaar, maar sinds PowerCLI versie 4.1 is er wel de CMDlet Get-VMHostPatch. Met deze CMDlet is het mogelijk om de geïnstalleerde patches van een ESX hosts uit te lezen. Een nadeel van deze methode is dat deze alleen werkt voor ESX 4 en hoger.

De onderstaande code gebruik ik om een overzicht te maken van alle ESX hosts in een vCenter omgeving:

Get-VMhost | Get-VMHostPatch | select @{N="Host";E={Get-VMhost -Id $_.VMhostid}}, @{N="Build";E={Get-VMhost -Id $_.VMhostid | Get-View | %{$_.Config.Product.build}}}, ID, InstallDate

donderdag 14 oktober 2010

Mailforwarding controleren met powershell

Sinds ik powershell gebruik zie ik steeds meer toepassingen en maak ik steeds minder gebruik van andere tools. Toch heeft powershell standaard nog wat meters te maken als het gaat om het beheer van Active Directory. Gelukkig vult Quest software dit gat op met een aantal AD-gerelateerde CMDlets, gebundeld onder de naam ActiveRoles Management Shell for Active Directory.

Door middel van deze tool is het een fluitje van een cent om te achterhalen op welke accounts email forwarding is ingeschakeld en naar welk adres de email gestuurd wordt. De onderstaande code geeft weer hoe ik dit voor elkaar heb gekregen.

get-qadobject -IncludeAllProperties -LdapFilter '(altrecipient=*)' | select name, email,
@{ Name = "altrecipient";
Expression = {get-qadobject $_.altrecipient -IncludeAllProperties | %{$_.mail}}
} | sort name | format-table -auto

maandag 31 augustus 2009

Herstellen resource pools door middel van SQL server en PowerCLI

Ooit per ongeluk DRS uitgezet op een VMware cluster? Onlangs gebeurde dit bij mijn huidige opdrachtgever en als gevolg van deze actie waren alle resource pools verdwenen. Gelukkig waren er maar 20 pools en konden we deze met de hand weer aanmaken, echter de toewijzing van virtuele machines (> 200) aan deze pools was wel een uitdaging.

Gelukkig werd er van de vCenter database regelmatig een backup gemaakt, dus de informatie was beschikbaar. Hoe deze te herstellen was wel een uitdaging. Deze procedure omschrijft de stappen die we hebben uitgevoerd om weer tot de originele configuratie te komen.

  1. Herstellen vCenter database

    Localiseer de backup die je eerder maakte en voer een restore uit onder een andere naam dan de originele database. Zo kunnen beide databases naast elkaar draaien.
  2. Haal de lijst van resource pools uit de VPX_ENTITY tabel

    Voer de volgende query uit om een lijst van resource pools uit de herstelde database te halen:
    select * from VPX_ENTITY (nolock)
    where TYPE_ID = 4
    and name != 'Resources'

    Controleer de output en exporteer deze lijst vervolgens door middel van een export wizard naar een CSV bestand.
  3. Aanmaken resource pools

    Het aanmaken van resource pools gaat het eenvoudigst door het eerder gemaakte CSV bestand te importeren in PowerCLI met het Import-CSV CMDlet. Gebruik hiervoor de volgende code:
    Import-Csv –Path FileName | foreach {
    New-Resourcepool -Location (Get-ResourcePool -Location ( Get-Cluster ClusterName ) -Name Resources) -Name $_.ColumnName
    }

  4. Ophalen resource pool configuratie

    Naast de namen is het ook wenselijk om reserveringen, shares en dergelijke te configureren. Deze waarden zijn niet in aparte kolommen opgeslagen, maar samengevoegd in een XML bericht in de kolom CONFIG_SPEC. Haal deze informatie op met de volgende query:
    select ID.NAME, RP.CONFIG_SPEC
    from VPX_RESOURCE_POOL RP (nolock)
    join VPX_ENTITY ID (nolock)
    on RP.ID = ID.ID
    where ID.TYPE_ID = 4
    and ID.NAME != 'Resources'
    order by ID.NAME

    In mijn situatie was het minder werk om deze informatie handmatig over te nemen in plaats van de XML berichten te parsen. Voor complexere omgevingen is het handiger om dit te automatiseren. Dit zou vanaf SQL 2005 met XQuery moeten kunnen, maar hier heb ik helaas nog niet mee gewerkt. :-(
  5. Lijst virtuele machines en resource pools maken

    Om te zorgen dat alle virtuele machines weer in hun oorspronkelijke resource pool worden geplaatst moet de relatie tussen VMs en resource pools worden opgehaald uit de database. Gebruik hiervoor de volgende query:
    select ID2.NAME AS VM_NAME, ID1.NAME AS RP_NAME
    from VPX_VM VM (nolock)
    join VPX_ENTITY ID1 (nolock)
    on ID1.ID = VM.RESOURCE_GROUP_ID
    join VPX_ENTITY ID2 (nolock)
    on ID2.ID = VM.ID
    order by ID2.NAME

    Controleer de output en exporteer deze lijst vervolgens door middel van een export wizard naar een CSV bestand.
  6. Virtuele machines verplaatsen

    Het eerder gemaakte CSV bestand kan ten slotte gebruikt worden om alle virtuele machines in de juiste resource groups te zetten. Gebruik hiervoor de volgende powershell code:

    Import-Csv –Path FileName | foreach {
    Get-VM -Name $_.ColumnNameVM | Move-VM -Destination (Get-ResourcePool $_.ColumnNameRP) -RunAsync
    }


Voor omgevingen met namen die niet-ASCII bevatten is het misschien handiger om niet met VM namen, maar met ID's te werken. Dit omdat de gegevens in de database met een andere codering wordt opgeslagen dan in de vCenter GUI of PowerCLI.

Een ander alternatief is om de urlencode functie van System.Web .NET class te gebruiken. Zie voor meer informatie hierover de volgende link: http://www.microsoft.com/technet/scriptcenter/topics/winpsh/convert/escape.mspx

vrijdag 17 juli 2009

Powershell troubleshooting

Voor het beheer van VMware gebruik ik steeds meer PowerShell en ook mijn Exchange admin collega's ontdekken de voordelen. Toch zijn bepaalde zaken weer nét even wat anders dan in een andere scripttaal. Een van die onderwerpen is troubleshooting.

Hiervoor heb ik 2 handige hulpmiddelen ontdekt, namelijk de standaard $error variabele en Start-Transcript, oftewel dit is min of meer de Powershell benadering van stderr en stdout.

De $error variabele is eigenlijk een array van errormeldingen die zich tijdens een Powershell sessie voordoen. Je kunt dus aan het eind van je script een controle doen of er iets in deze variabele staat en deze eventueel naar een bestand laten schrijven. Zie het onderstaande voorbeeldje om te zien hoe ik dit gebruik in mijn scripts:

#Print error messages - if any - to a file
if ($error.count -gt 0)
{
$error | Out-File stderr.log
}

Het Start-Transcript CMDlet is nog eenvoudiger. Gebruik dit commando aan het begin van je script en alle output van je script wordt naar een opgegeven bestand geschreven. Zet aan het eind van je script - of eerder indien gewenst - het Stop-Transcript commando en er wordt niet meer gelogd.