PowerShell címkéhez tartozó bejegyzések

Exception calling "SqlBackup" with "1" argument(s)

Az egyik szerverünkön az alábbi PowerShell script végzi az SQL Server adatbázisok mentését:

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null

$server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") $dbInstance
$backup = New-Object ("Microsoft.SqlServer.Management.Smo.Backup")
$backup.Action = "Database"
$backup.BackupSetDescription = "Full backup of " + $dbName
$backup.BackupSetName = $dbName + " backup"
$backup.Database = $dbName
$backup.MediaDescription = "Disk"
$backup.Devices.AddDevice("$localSqlBackupPath", "File")
$backup.SqlBackup($server)

Ez a kód most már évek óta működik rendesen, szépen készülnek a backupok naponta. Ám az utóbbi időben érdekesen kezdett viselkedni a szkript: egyes adatbázisokat mindig lementett, másokat pedig – amikkel korábban nem volt gond – többnyire nem. A naplóba az alábbi hibaüzenet került:

Exception calling "SqlBackup" with "1" argument(s): 
"Backup failed for Server 'MyServer\MySqlInstance'. " At D:\Backups\BackupSite.ps1:151 char:22 + $backup.SqlBackup <<<< ($server) + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodException

Nehezen derült ki, hogy a hibának semmi köze a függvény meghívásának módjához, hanem a problémát az okozza, hogy megnőtt az adatbázis, és az SqlBackup függvény 10 perc után timeoutolódik. A ServerConnection objektum StatementTimeout tulajdonságával lehet kikapcsolni az időtúllépés figyelését:

$server.ConnectionContext.StatementTimeout = 0

 

Technorati-címkék: ,
Reklámok

Gyakori PowerShell kérdések

Nem írok sűrűn PowerShell szkripteket, ezért van néhány olyan probléma, amibe gyakran belefutok. Íme a megoldásuk, hátha más is hasznát veszi:

Kommentezés

# Egysoros komment kettőskereszt után
<#
  Ez egy
  több soron 
  átnyúló megjegyzés
#>

Leírás

A Get-Help cmdlet által kiírandó leírás tartalmát a szkript elejére tett komment blokkban adhatjuk meg az alábbi formában:

<#
.SYNOPSIS
    Rövid leírás...    
.DESCRIPTION
    Hosszú leírás... 
.PARAMETER MyParam1
    A MyParam1 paraméter leírása...
.PARAMETER MyParam2
    A MyParam2 paraméter leírása...
.EXAMPLE
    C:\PS> .\MyScript.ps1 –MyParam1 "egy"  
Az első példa leírása... .EXAMPLE C:\PS> .\MyScript.ps1 –MyParam2 2012 A második példa leírása... .NOTES Egyéb megjegyzés, például szerző, dátum...
Author: György Balássy Date: 2012.07.11. #>

Bemeneti paraméterek

Egy szkript vagy függvény bemeneti paramétereit a Param kulcsszóval definiálhatjuk. A paramétereknek adhatunk alapértéket is:

Param(
    $MyParam1,
    $MyParam2 = 10
)

Paraméter validálás

A paramétereknél a .NET-es attribútumokhoz hasonló szintakszissal megadhatunk típust, illetve néhány kényszert is:

Param(
    [parameter(Mandatory=$true)]  
[string]
[ValidateScript({Test-Path $_ -PathType 'Container'})] $MyParam1, [parameter(Mandatory=$false)]
[int]
[ValidateRange(-1, 31)] $MyParam2 = 10 )

Ezeken az attribútumokon kívül van még ValidateLength, ValidateCount, ValidatePattern, ValidateNotNull, ValidateNotNullOrEmpty is.

Mappa létezésének ellenőrzése

A Test-Path cmdlet segítségével ellenőrizhetjük, hogy egy vagy több mappa vagy fájl (általánosabban: útvonal) létezik-e, vagy akár csak azt, hogy a megadott útvonal érvényes-e (ld. –IsValid kapcsoló). A cmdlet $true értékkel tér vissza, ha az adott útvonal létezik:

if( $myPath -ne $null -and ( Test-Path $myPath ) -eq $true )
{
    Remove-Item $myPath -Recurse
}

Szkript leállítása

Egy futó szkript leállítására használhatjuk az exit kulcsszót, ami után tetszőleges hibakódot megadhatunk. Ha hibajelzéssel akarjuk leállítani a szkriptet, akkor jobb a throw kulcsszót használni, ami után megadhatunk egy szöveges hibaüzenetet és ami 1 hibakóddal állítja le a szkript futását. Normál esetben a szkript 0 hibakóddal fejeződik be.

if( ( Test-Path $cmd ) -eq $false ) 
{
throw "A $cmd értéke nem megfelelő!"
}

Színes betűk a konzolra

Ha jobban el akarjuk különíteni a szkriptünk által kiírt üzeneteket a felhasznált cmdletek vagy külső programok üzeneteitől, akkor írhatunk színesen a konzolra:

Write-Host "Valami történik..." -ForegroundColor Green

Dátum formázása

Néha szükségünk van a mai dátumra, méghozzá valamilyen formátumban, amit előállíthatunk például így:

$now = Get-Date -format yyyyMMdd_HHmmss;

Kimenet elhallgattatása

A kimenet “némítására” parancssorban általában a >null átirányítást szoktuk használni, de tapasztalataim szerint ez egy PowerShell szkriptben nem mindig azt csinálja, amit szeretnénk. Ez esetben bátran használhatjuk az Out-Null cmdletet:

mkdir $targetDir | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("MyAssembly") | Out-Null

Module vagy snap-in betöltése

Találkoztam olyan PowerShell bővítménnyel, amit PowerShell 1.0 alatt snapinként, 2.0 alatt pedig modulként kellett betölteni. Szerencsére le tudjuk kérdezni a PowerShell verziószámát és megifelhetjük a betöltést:

if( $PSVersionTable.PSVersion.Major -ge 2 )
{
  Import-Module MyModule
}
else
{
   Add-PSSnapin MyModule
}

Lásd Using Modules and Snap-Ins.

SQL adatbázis mentése

SMO segítségével így menthetünk SQL adatbázist:

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum")

$s = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "(local)" 
$b = New-Object ("Microsoft.SqlServer.Management.Smo.Backup") $b.Action = "Database" $b.BackupSetDescription = "Full Northwind backup" $b.BackupSetName = "Northwind backup" $b.Database = "Northwind"
$b.MediaDescription = "Disk" $b.Devices.AddDevice("C:\Backup\MyBackup.bak", "File") $b.SqlBackup($s)

IIS konfiguráció mentése

Az IIS konfiguráció mentéséhez használhatjuk az IIS  PowerShell Snap-Int:

Import-Module WebAdministration   # vagy  Add-PSSnapin
Backup-WebConfiguration "MyBackupName"

Szövegfájl sorainak feldolgozása

Get-Content $filePath | Foreach-Object
{ 
  # Sor feldolgozása a $_ változóval
}

 

A PowerShell megismeréséhez nagyon hasznos forrás Soós Tibor Windows PowerShell 2.0 rendszergazdáknak c. könyve.

 

Technorati-címkék: ,,,

Az IIS 7.0 szkriptelése PowerShellből

Az IIS 7.0 szkriptelése PowerShellből A Windows PowerShell Snap-in for IIS 7.0 ingyenesen letölthető kiegészítés, melynek segítségével közvetlenül PowerShell parancssorból kezelhetjük az IIS 7.0 konfigurációs beállításait, és futási idejű adatokat kérdezhetünk le a webkiszolgálótól. A snap-in regisztrálása után webhelyek, alkalmazáskészletek, webalkalmazások, virtuális mappák, kérések, munkafolyamatok és .NET alkalmazástartományok létrehozása, törlése és tulajdonságaik módosítása elvégezhető PowerShellből.

A snap-in létrehoz egy IIS: “meghajtót”, amelyben a mappa hierarchiához hasonlóan navigálhatunk a az IIS objektumok között. Objektumok lekérdezéséhez a Get-Item, létrehozásához és törléséhez a New-Item és a Remove-Item commandleteket használhatjuk. Az objektumok tulajdonságai a Get-ItemProperty parancs segítségével kérdezhetőek le és a Set-ItemProperty parancs segítségével állíthatóak be.

Az IIS tetszőleges konfigurációs beállításai lekérdezhetőek és beállíthatóak a Get-WebConfiguration és Set-WebConfiguration, valamint a Get-WebConfigurationProperty és Set-WebConfigurationProperty commandletek segítségével. Az XML beállítások közé új elemet felvenni az Add-, törölni a Remove-WebConfigurationProperty segítségével lehet. Teljes szekció a Clear-WebConfiguration commandlettel törölhető.

Demó

A demóban bemutatjuk, hogyan használhatjuk a PowerShellt új webhelyek, alkalmazások és alkalmazáskészletek létrehozására és az IIS 7.0 konfigurációs beállításainak módosítására.

IIS 7.0 PowerShell provider demó - a demó megtekintéséhez kattints a képre.

Lejátszáshoz kattints a képre!

Letöltés: PowerShell.wmv (24:23, 131 MB)

Első lépések

Indítsuk el a Server Managert és telepítsük fel a Windows PowerShell nevű Feature-t, majd töltsük le és telepítsük a Windows PowerShell Snap-in for IIS 7.0-t. Indítsuk el a Start Menüből az IIS PowerShell Management Console programot vagy a standard PowerShell promptban regisztráljuk az IIS PowerShell bővítményt az alábbi parancs futtatásával:

  PS C:> & "$env:programfilesIISPowerShellProvideriisConsole.psc1"

Jó tudni

A snap-in által támogatott commandletek listája lekérdezhető az alábbi paranccsal:

  Get-Command –pssnapin IISProviderSnapIn

IIS 7.5

A Windows Server 2008 R2-ben megjelent IIS 7.5 már beépítetten tartalmaz PowerShell támogatást a webszerver objektumainak kezeléséhez. Itt az új architektúrának megfelelően nem snap-in, hanem PowerShell module fogja össze az IIS 7.5 kezelésére szolgáló commandleteket. A module betöltését az alábbi paranccsal végezhetjük el:

  Import-Module WebAdministration

A betöltött commandletek listáját pedig ezzel a paranccsal kérdezhetjük le:

  Get-Command –Module WebAdministration

További információk

 

Technorati-címkék: ,,,

Azonos típusú fájlok kiszedése alkönyvtárakból

Gyakran előfordul, hogy egy mappa végtelen mennyiségű alkönyvtárából kellene minden fájlt vagy éppen egy feltételnek megfelelő fájlokat kimásolni. Régen erre a Windows Explorer Search funkcióját használtam, de a Vista óta erre a célra egyszerűen nem áll kézre. Mivel nem vagyok Total Commander függő, ezért jobb megoldást kerestem és hamar sikerült kikötnöm a PowerShellnél.

Mint ahogy azt a Powershellnél már megszokhattuk, egyetlen sor a megoldás:

    Get-ChildItem -filter *.xls -recurse | Copy-Item -destination C:celmappa

Elsőre furcsa volt, hogy bár a Get-ChildItemre működik a dir alias, a /s helyett mégis –recurse kell, és a copynak megfelelő Copy-Itemet is kicsit másként kell paraméterezni, hamar hozzá lehet szokni.

Technorati Tags:

Jeffrey Snoverrel beszélgettem

A TechEd kaliberű rendezvények egyik előnye, hogy az ember személyesen találkozhat azokkal, akik igazán közel vannak a tűzhöz. Ez persze nem minden téma esetén van így, mert vannak termékek, ahol az "evangélisták" tartják az előadásokat, de a kisebb csapatok esetén az előadók gyakran egyben a projekt szakmai agyai is.

Így történt ez az idei TechEden is, ahol a PowerShell előadást maga Jeffrey Snover tartotta, akit egyben a PowerShell atyjának is tartanak. A téma egyébként a PowerShell 2 volt, amire mindenképp érdemes figyelmet fordítani. Hogy csak két dolgot említsek: távoli adminisztráció és grafikus felület a commandletek írásához. Jól hangzik, nem? 😉

Őt sikerült a Speaker Lounge-ban egy igen érdekes beszélgetésre elkapnom, ahol számos újdonságot elárult mind a PowerShell 2-ről, mind pedig arról, hogy hogyan működik ez a fejlesztő csapat a Microsofton belül. Ennek a beszélgetésnek a nem NDA-s részéről felvételt is készítettem, ami megtekinthető az MSDN Kompetencia Központ oldalán az alábbi képre kattinva:

Jeffrey Snover interjú

A PowerShell csapat egyébként tényleg nem nagy, mindössze körülbelül harmincan dolgoznak azon az eszközön, ami a közeljövőben minden szerver termékben jelen lesz. Az Exchange 2007 már használja, és már az SQL Server 2008 CTP változatát is lehet szkriptelni. Ja kérem, úgy könnyű, ha az ember mögött ott áll a fővezér, Bob Muglia, aki komolyan hisz a PowerShellben 🙂

Íme néhány tipp a kezdeti lépések megtételéhez:

  1. PowerShell letöltése
  2. A telepítő feltesz néhány rövid doksit (külön is letölthetőek), azokat érdemes átböngészni
  3. Ingyenes e-Book Frank Kochtól
  4. Könnyen emészthető könyv a PowerShell: Step-by-Step az MS Presstől

Ennyi után már bátran nekivághatunk saját szkriptek írásának, bár fejlesztőkhöz inkább a saját commandletek készítése illik, de erről majd legközelebb…

 

Technorati tags: , ,

SharePoint backup PowerShellel

Nem sok olyan szörnyű dolog van az életben, mint egy korábban írt forráskódot újra elővenni, hogy valamit módosítsunk rajta. A dolog egy kicsit kellemesebb, ha a kódot nem más írta, de ha VB Scriptben van, akkor azt semmivel sem lehet ellensúlyozni!

Ma abba a problémába futottam bele, hogy egy korábban írt backup scriptet kellene frissíteni, ami a tanszéki Windows SharePoint Servicest menti le. Furdalt a kíváncsiság, hogyan lehetne megoldani a feladatot PowerShellel…

Először is be kell töltenünk a Microsoft.SharePoint.dll-t:

[system.reflection.assembly]::LoadWithPartialName( "Microsoft.SharePoint" )

Ha ez a válasz, akkor jó, a hallgatás hibát jelent 🙂

GAC    Version        Location
---    -------        --------
True   v2.0.50727     C:WINDOWSassemblyGAC_MSILMicrosoft.SharePoint12.0.0.0__71e9bce111e9429cMicrosoft.SharePo...

Kellene egy SPGlobalAdmin objektum:

$globaladmin = New-Object Microsoft.SharePoint.Administration.SPGlobalAdmin

Aki nem hiszi, hogy létrejött, csak írja be, hogy $globaladmin és valami hasonló lesz a válasz:

Config                         : Microsoft.SharePoint.Administration.SPGlobalConfig
Version                        : 12.0.0.4518
AllowUnsafeUpdates             : True
ApplicationPools               : {DefaultAppPool, Intranet Pool, SharePoint Central Administration v3, WSS Admin Pool}
AdminPortUrl                   : http://maffia:4444/
AdminPortApplicationPoolId     : SharePoint Central Administration v3
AdminPortIISInstanceId         : 201702596
VirtualServers                 : {MAFFIA, MAFFIA, 152.66.251.54, MAFFIA...}
VirtualServerNames             : {Intranet Web Site}
ConfigDatabase                 : Microsoft.SharePoint.Administration.SPConfigDatabase
ConfigDatabaseServer           : MAFFIA
ConfigDatabaseName             : IntranetConfigDB
UseNtAuthenticationForDatabase : True
ConfigDatabaseUser             :
UsageSettings                  : SPUsageSettings Parent=SPWebService Name=WSS_Administration
OutboundSmtpServer             : MAIL
MailFromAddress                : no-reply@aut.bme.hu
MailReplyToAddress             : no-reply@aut.bme.hu
MailCodePage                   : 0
AdminFormDigest                : 0xA2F82FA8DAE0854788585078B59D6C2AD84A69D5FFCC8ED01CC1430E1A597E5825B9889FC5D2871FA149
                                 4111C72B52F0D248D4ED812A175485F5AC15B5A0AF7F,10 Sep 2007 17:32:09 -0000
AccountCreationModeEnabled     : False
InstalledLanguages             : {Magyar}
ServerLanguage                 : Microsoft.SharePoint.SPLanguage
TimeZones                      : {39, 16, 15, 14...}
UseHostHeaderAsSiteName        : False

 Tegyük el a gyökér webhely címét egy változóba:

$url = "https://maffia"

Nyissuk meg a címen elérhető SPVirtualServer objektumot:

$vserver = $globaladmin.OpenVirtualServer( $url )

Nézzük meg, hogy ez mit tud:

PS C:> $vserver

IisWebSiteSettings         : Microsoft.SharePoint.Administration.SPIisSettings
WebApplication             : SPWebApplication Name=Intranet Web Site Parent=SPWebService
HostName                   : 152.66.251.54
Port                       : 80
Url                        : https://intranet/
CatchAccessDeniedException : False
Sites                      : {a7b2b582-2017-49a7-8524-873d4aec27ae, ec4d8bdb-1ce7-427e-a0f1-3c5a9fc813d0, 7dc69ef5-ae41
                             -4afa-94d6-7f1b933509af, 2e764d06-842c-45d4-be57-ce6f28c9d110...}
Config                     : Microsoft.SharePoint.Administration.SPVirtualServerConfig
IISInstanceId              : 2049022554
VirtualServerId            : 32895ea5-1dc1-47ba-b25f-d9371aa50c0e
Description                : Intranet Web Site
PresenceEnabled            : True
Version                    : 12.0.0.4518
State                      : Ready
ApplicationPoolId          : Intranet Site Pool
OutboundSmtpServer         : MAIL
MailFromAddress            : no-reply@aut.bme.hu
MailReplyToAddress         : no-reply@aut.bme.hu
MailCodePage               : 0
ContentDatabases           :

Kérdezzük meg, hogy ennek az objektumnak milyen tulajdonságai vannak:

PS C:> $vserver | Get-Member -memberType property

   TypeName: Microsoft.SharePoint.Administration.SPVirtualServer

Name                       MemberType Definition
----                       ---------- ----------
ApplicationPoolId          Property   System.String ApplicationPoolId {get;}
CatchAccessDeniedException Property   System.Boolean CatchAccessDeniedException {get;set;}
Config                     Property   Microsoft.SharePoint.Administration.SPVirtualServerConfig Config {get;}
ContentDatabases           Property   Microsoft.SharePoint.Administration.SPContentDatabaseCollection ContentDatabas...
Description                Property   System.String Description {get;}
HostName                   Property   System.String HostName {get;}
IISInstanceId              Property   System.Int32 IISInstanceId {get;}
IisWebSiteSettings         Property   Microsoft.SharePoint.Administration.SPIisSettings IisWebSiteSettings {get;}
MailCodePage               Property   System.Int32 MailCodePage {get;}
MailFromAddress            Property   System.String MailFromAddress {get;}
MailReplyToAddress         Property   System.String MailReplyToAddress {get;}
OutboundSmtpServer         Property   System.String OutboundSmtpServer {get;}
Port                       Property   System.Int32 Port {get;}
PresenceEnabled            Property   System.Boolean PresenceEnabled {get;}
Sites                      Property   Microsoft.SharePoint.Administration.SPSiteCollection Sites {get;}
State                      Property   Microsoft.SharePoint.Administration.SPVirtualServerState State {get;}
Url                        Property   System.Uri Url {get;}
Version                    Property   System.Version Version {get;}
VirtualServerId            Property   System.Guid VirtualServerId {get;}
WebApplication             Property   Microsoft.SharePoint.Administration.SPWebApplication WebApplication {get;}

A Sites tulajdonság érdekes számunkra, ugyanis az SPSiteCollection osztály tartalmaz egy Backup metódust és éppen arra van szükségünk. Megjegyzem az stsadm.exe is éppen ezt hívja. De előbb nézzük, mit tudunk a webhelyekről, pontosabban webhely gyűjteményekről, hiszen nem SPWeb, hanem SPSite objektumokkal dolgozunk. Bátran be lehet írni, hogy $vserver.Sites[0], hogy megnézzük, mit mond a PowerShell egy webhelyről és természetesen ezt is belecsövezhetjük a Get-Member pajtásba.

Kérhetünk egy átlátható listát a virtuális kiszolgálón található webhely gyűjteményekről:

PS C:> $vserver.Sites | Format-Table Url, RootWeb

Url                                                         RootWeb
---                                                         -------
https://intranet                                            BME AAIT Intranet
https://intranet/courses/dotnet                             Csoportwebhely
https://intranet/courses/portals                            Webportálok fejlesztése
https://intranet/courses/SzofTechBSc                        A Szoftvertechnikák (BSc) tárgy munkaterülete
https://intranet/projects/seagull                           Seagull Project
https://intranet/projects/vjt                               Csoportwebhely
https://intranet/projects/vmts                              Visual Modeling and Transformation System
https://intranet/sites/eBooks                               Elektronikus könyvtár
https://intranet/sites/mscorpevents                         Microsoft Nemzetközi Rendezvény Archívum
https://intranet/sites/msevents                             Microsoft Hazai Rendezvény Archívum

Ebből rögtön látszik, hogy egyesek lusták átnevezni a webhelyüket. (Egyébként van itt egy csalás, ugyanis a RootWeb egy SPWeb típusú objektum, nem csak egy string.) A rendszergazda-lét előnye, hogy az ember retorziókat is alkalmazhat, például nem menti le a hanyag gazdik webhelyeit:

PS C:> $vserver.Sites | Where-Object{ $_.RootWeb.Title -ne "Csoportwebhely"  } | Format-Table Url, RootWeb

Url                                                         RootWeb
---                                                         -------
https://intranet                                            BME AAIT Intranet
https://intranet/courses/portals                            Webportálok fejlesztése
https://intranet/courses/SzofTechBSc                        A Szoftvertechnikák (BSc) tárgy munkaterülete
https://intranet/projects/seagull                           Seagull Project
https://intranet/projects/vmts                              Visual Modeling and Transformation System
https://intranet/sites/eBooks                               Elektronikus könyvtár
https://intranet/sites/mscorpevents                         Microsoft Nemzetközi Rendezvény Archívum
https://intranet/sites/msevents                             Microsoft Hazai Rendezvény Archívum

Egyetlen webhelyet így menthetünk le:

$vserver.Sites.Backup( "https://intranet/projects/seagull", "E:Backupsseagull.backup", $true )

A hátralévő részt mindenki el tudja képzelni: ForEach-Object segítségével ciklusba zavarjuk a metódushívást vagy függvényt gyártunk az egészből.

Már játszom egy ideje a PowerShellel, de még mindig tudok lelkesedni érte. A Windows Workflow Foundation vagy a SharePoint ennyi idő után már nem mert a szemem elé kerülni 🙂

 

Technorati tags: , , ,