úterý 1. května 2012

Powershell a excel


Vzdálená inventura PC s výstupem do excelu
Inventarizace majetku.PC deník nebo jen info co mám vlastně v doméně.Ve zkratce potřebujeme informace o PC,typu jaká RAM,
kolik HDD co je nainstalováno atd.Vcelku jednoduchý úkol pokud použijeme powershell.Pro všechny informace si sáhneme vzdáleně a ani nemusíme vstát ze židle.Vše si nasměrujeme do nějakého jednoduchého výstupu(typicky txt)a jsme za vodou.
ALE pokud tyto informace předáváme dál(a hlavně výše),budeme mít velký problém.Nadřízení xmrti milují když mají data nějaký grafický kabát.Většinou excel-tabulka hezky vybarvená všelijak orámovaná různými druhy písma osazená a grafy............
 ……  HODNĚ  grafů.
Rozhodně nebudeme získaná data otrocky datlovat do excelovské tabulky ručně.Chce to skript který si vzdáleně sáhne na kontrolovaný počítač,nasbírá data a ty rovnou vepíše do tabulky kterou ještě navrch nějak graficky upraví.
Klidně by se tento příspěvek mohl  jmenovat powershellovské hrátky s excelem protože záměrně využívám několik způsobů jak modifikovat tabulku.Nešlo tu o to abych vyrobil tu nejkrásnější tabulku.Chtěl jsem jen demonstrovat co vše powershell umí s excelem.
No on toho umí samozřejmě ještě více ale toto jsou jakési základy.
Ve skriptu je kus kódu který pomocí powershellu zjistí cd-key do windows.Tento skript není můj,našel jsem ho na internetu a protože se mi nepodařilo zjistit autora nemohu uvést zdroj.

Zdroje:
Se zarovnáním grafu mi hodně pomohla tato stránka:  
Další info a tabulka barev je zde  :

PS:záměrně jednu a tu samou věc dělám na několik způsobů.Může se zdát že jeden ze způsobů je zdlouhavý nebo nesystémový  ale každý zápis si najde své využití.
A nakonec jedno upozornění.Po spuštění skriptu se zdánlivě nic neděje.To je dáno tím že hned na začátku je procedura jenž zjišťuje nainstalované programy a to chvilku trvá.Odhadem od 2 od 10min.





################################  Vytvoril:Petr Skrivan ####################################


#zde uvedte jmeno kontrolovaneho pc
$comp= "kontrolovanePC"
#zjistime nainstalovane programy na vzdalenem pc
$nainstalovano=get-wmiobject win32_product -computername $comp |foreach {$_.name}
#novy objekt konkretne excel
$excel=new-object -comobject excel.application
$excel.visible=$true
#promenne $sesit priradime novou knihu 
$sesit=$excel.workbooks.add()
# promenne $list priradime novy list v sesitu
$list=$sesit.worksheets.item(1)
#sloupec cislo 3 tedy cecko roztahneme na konkretni hodnotu
$list.Columns.Item(3).columnWidth = 80
#sloupec pismeno e roztahneme na konkretni hodnotu
$list.Columns.Item("e").columnWidth = 15
$list.Columns.Item(6).columnWidth = 15
$list.Columns.Item(4).columnWidth = 1
#radek cislo 7 roztahneme na pozadovanou hodnotu
$list.Rows.item(7).RowHeight = 2
$list.Rows.item(4).RowHeight = 2
#sloupce g a i roztahneme na pozadovanou hodnotu
$list.Range("g:i").columnWidth=11
#do promenne si ulozime urcity rozsah bunek
$nazevpc= $list.Range("c2:i3")
#a pak vybrane bunky spojime
$nazevpc.Mergecells= $true
#spojene bunky obarvime
$nazevpc.Interior.colorindex= 44
#spojene bunky oramujeme
$nazevpc.Borders.LineStyle= 2
#zadame hodnotu nebo retezec ktery budou spojene bunky obsahovat
$nazevpc.FormulaR1C1 = ("Výpis parametrů PC  >> $comp << ")
#ve spojenych bunkach zarovname text na stred jak horizontalne tak vertikalne
$nazevpc.HorizontalAlignment= -4108 ; $nazevpc.VerticalAlignment= -4108
#promenne $programy priradime rozsah bunek
$programy=$list.range("c8:c10")
#zde sloucime vyse vybrane bunky
$programy.MergeCells=$true
#vyse sloucene bunky budou mit zelenou barvu
$programy.Interior.ColorIndex= 19
#obsah bunky c8 (coz je momentalne nekolik sloucenych bunek viz vyse)
$list.Range("c8").FormulaR1C1= "Nainstalovane Programy"
#zarovnani textu v bunce c8 na stred horizontalne
$list.Range("c8").HorizontalAlignment = -4108
#zarovnani textu v bunce c8 na stred vertikalne
$list.Range("c8").verticalAlignment = -4108
#zmena fontu v bunce c8
$list.Range("c8").Font.name = "elephant"
#zmena velikosti fontu bunce c8
$programy.Font.Size= 15
#zmena oramovani ve sloucenych bunkach ted tedy v c8
$programy.Borders.LineStyle= 6
$a=10
#do roury posleme nainstalovane programy ktere si nasledne jeden po druhem vyzvedneme v..
#.....podobe promenne $hodnota
foreach ($hodnota in $nainstalovano){
$a ++
#do bunky c$a napise program aktualne proudici v roure
$list.Range("c$a").FormulaR1C1= $hodnota
#bunku c$a obarvi na zelenou
$list.Range("c$a").Interior.ColorIndex = 19
}
#do promenne ulozi celou tabulku
$celatabulka=$list.range("c11:c$a")
#oramujeme celou tabulku
$celatabulka.Borders.LineStyle= 7
#do promenne $disky si ulozime bunku e11
$disky=$list.range("e11")
#bunku e11 obarvime
$disky.Interior.ColorIndex = 22
#do bunky e11 napiseme text
$list.Range("e11").FormulaR1C1= "HDD celkově"
#text v bunce e11 bude formatovan na stred
$disky.HorizontalAlignment= -4108
#bunku e11 oramujeme
$disky.Borders.LineStyle= 7
$diskyfree=$list.range("f11")
$diskyfree.Interior.ColorIndex = 35
$list.Range("f11").FormulaR1C1= "HDD volno"
$diskyfree.HorizontalAlignment= -4108
$diskyfree.Borders.LineStyle= 7
#do promenne si ulozime info o HDD a filtrujeme jen lokalni disky
$hddvse= Get-WmiObject Win32_LogicalDisk -ComputerName $comp|Where-Object{$_.drivetype -eq 3}
#do promenne ulozime celkovou velikost vsech HDD zaokrouhlenou na GB
$mistocelkem= ($hddvse | Measure-Object size -sum).sum/1gb
#zaokrouhlime celkovou velikost vsech HDD
$mistocelkemzaokrouhleno=([System.Math]::Round($mistocelkem))
#do promenne ulozime celkovou volnou kapacitu vsech HDD zaokrouhlenou na GB
$volnemistocelkem= ($hddvse | Measure-Object freespace -sum).sum/1gb
#zaokrouhlime celkovou volnou kapacitu vsech HDD
$volnemistocelkemzaokrouhleno=([System.Math]::Round($volnemistocelkem))
#vypocitame si obsazene misto
$obsazenemisto=$mistocelkemzaokrouhleno - $volnemistocelkemzaokrouhleno
$b=12
#info o HDD zasleme do roury a postupne vyzvedneme pod promennou $argument
foreach ($argument in $hddvse){
#do promenne si ulozime jmena vsech disku
$nazevhdd=($argument.DeviceID)
#do promenne si ulozime velikost vsech disku
$velikost=($argument.size/ 1GB)
#do promenne si ulozime velikost volneho misto
$volnemisto=($argument.FreeSpace/ 1GB)
#zaokroulime volne misto na cele cislo
$prevedenovolno=([System.Math]::Round($volnemisto))
#zaokrouhlime celkove misto na cele cislo
$prevedenocelk=([System.Math]::Round($velikost))
#do dane bunky zapise nazev hdd a zaokrouhlenou celkovou velikost
$list.Range("e$b").FormulaR1C1=("$nazevhdd $prevedenocelk GB " )
#a bunku obarvi
$list.Range("e$b").Interior.ColorIndex = 22
#do dane bunky zapise nazev hdd a zaokrouhlenou volnou kapacitu
$list.Range("f$b").FormulaR1C1= ("$nazevhdd $prevedenovolno GB " )
#a bunku obarvi
$list.Range("f$b").Interior.ColorIndex = 35
$b++
}
#zde si pripravime pomocne bunky odkud si graf vezme data v konecnem vysledku nebudou
#..tyto bunky viditelne(skryje je graf)
$list.Range("F23").formular1c1=("HDD celkem obsazeno")
$list.Range("E23").formular1c1=("HDD celkem volno")
$list.Range("F24").formular1c1=("$obsazenemisto")
$list.Range("E24").formular1c1=("$volnemistocelkemzaokrouhleno")
#zjisteme nazev procesoru + info o taktu
$procesor= Get-WmiObject Win32_Processor -ComputerName $comp | foreach {$_.name }
$list.Range("c5:i5").mergecells=$true
$list.Range("c5:i5").HorizontalAlignment= -4108
$list.Range("c5").FormulaR1C1= ("CPU: $procesor")
$list.Range("c5").Interior.ColorIndex = 42
#zjistime typ graficke karty -filtrujeme jen iformaci name
$grafika= Get-WmiObject Win32_VideoController -ComputerName $comp |foreach {$_.name}
$list.Range("c6:i6").mergecells=$true
$list.Range("c6:i6").HorizontalAlignment= -4108
$list.Range("c6").FormulaR1C1= ("GPU: $grafika")
$list.Range("c6").Interior.ColorIndex = 42
#zjistime info o pameti
$ram= Get-WmiObject Win32_PhysicalMemory -ComputerName $comp
#protoze muzeme dostat vice hodnot(vice objektu)tak ty nejdrive secteme a
#zaokrouhlime na MB vse ulozime do promenne
$kapacitaram= ($ram | Measure-Object capacity -sum).sum/1mb
#pocet modulu ram zjistime takto
$pocetram= $ram.Length
#pokud vydelime celkovou kapacitu poctem modulu,zjistime kapacitu jednoho modulu
$jednaram=$kapacitaram/$pocetram
#zde ziskane hodnoty rozhazime do bunek
$pameti =$list.range("g11:i11")
$pameti.MergeCells=$true
$pameti.HorizontalAlignment= -4108
$pameti.FormulaR1C1= ("Operační Pamět")
$pameti.Borders.LineStyle= 6
$list.Range("g12").FormulaR1C1= ("Moduly ks")
$list.Range("h12").FormulaR1C1= ("Kapacita")
$list.Range("i12").FormulaR1C1= ("Celkem MB")
$list.Range("g13").FormulaR1C1= ("$pocetram")
$list.Range("h13").FormulaR1C1= ("$jednaram")
$list.Range("i13").FormulaR1C1= ("$kapacitaram")
$list.Range("g11:i13").Interior.ColorIndex= 15
$list.Range("g12:i13").Borders.LineStyle= 7
$list.Range("e8:i8").mergecells=$true
$list.Range("e8:i8").HorizontalAlignment= -4108
$list.Range("e8").FormulaR1C1= ("INFO : Operační sytém")
$list.Range("e8:i8").Borders.LineStyle= 7
$list.Range("e8:e10").Interior.ColorIndex= 17
#zjistime info o OS
$os= Get-WmiObject Win32_OperatingSystem -computername $comp
#do promenne ulozime jen to co nas zajima a to je verze OS
$osname=$os.caption
$list.Range("e9:i9").mergecells=$true
$list.Range("e9").FormulaR1C1= ("Verze OS: $osname ")
<#
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
Tento kus kodu zjisti CD-KEY u windows.Neni muj nasel jsem ho na interneru
uvedl bych autora ale nepodarilo se mi ho zjistit.
#>
$hklm = 2147483650
$regPath = "Software\Microsoft\Windows NT\CurrentVersion"
$regValue = "DigitalProductId"
$productKey = $null
$wmi = [WMIClass]"\\$comp\root\default:stdRegProv"
$data = $wmi.GetBinaryValue($hklm,$regPath,$regValue)
$binArray = ($data.uValue)[52..66]
$charsArray = "B","C","D","F","G","H","J","K","M","P","Q","R","T","V","W","X","Y","2","3","4","6","7","8","9"
For ($i = 24; $i -ge 0; $i--) {
$k = 0
For ($j = 14; $j -ge 0; $j--) {
$k = $k * 256 -bxor $binArray[$j]
$binArray[$j] = [math]::truncate($k / 24)
$k = $k % 24
}
$productKey = $charsArray[$k] + $productKey
If (($i % 5 -eq 0) -and ($i -ne 0)) {
$productKey = "-" + $productKey
}
}
#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

$list.Range("e10:i10").mergecells=$true
$list.Range("e10").FormulaR1C1= ("CD-KEY: $productKey")
#urcime kde si graf veme data
$range = $list.range("E23:F24")
#pridej tvar(tabulku)do stavajiciho listu
$tabulka = $list.shapes.addChart().chart
#typ tabulky(grafu) vsechny typy grafu neleznete v odkazu nize
# http://msdn.microsoft.com/en-us/library/bb241008(v=office.12).aspx
$tabulka.chartType = 5
#kde bude graf brat data je dano predem definovanou promennou
$tabulka.setSourceData($range)
#do promenne urcime kde tabulka bude
$zarovnej = $list.Range("E20:i32")
#do promenne graf ulozime soucasnou tabulku(graf je taky tabulka)
$graf = $tabulka.Parent
#horni cara grafu bude na radku 20
$graf.Top = $zarovnej.Top
#levy okraj bude ve sloupci E
$graf.Left = $zarovnej.Left
#vyska grafu bude odpovidat radkum 20 - 32
$graf.Height = $zarovnej.Height
#sirka grafu bude E - I
$graf.Width = $zarovnej.Width
#nadpis tabulky bude vyditelny
$tabulka.HasTitle = $true
#text nadpisu
$tabulka.ChartTitle.caption = "Vsechny pevne disky volno/obsazeno"
#popisek grafu pokud tento radek vynechate bude to zakladni graf
$tabulka.ApplyDataLabels(5)

#pokud chcete jine barevne pozadi tabulky (staci odkomentovat radek nize)
#$tabulka.ChartArea.Interior.colorindex = 24

#uloz celou tabulku jako xlsx pojmenuj ji dle jmena kontrolovaneho pc a to vse dle zadane cesty
$sesit.SaveAs("C:\$comp.xlsx")

#ukonci excell..pokud si chcete tabulku ihned prohlednout tak tento radek zakomentujte
$Excel.Quit()



Výsledek našeho snažení