Prosessien tietojen etsiminen Powershellillä
UNIX-tyyppissä järjestelmissä prosessitaulun tarkastelu on helppoa ps-komennolla. Samainen komento löytyy Powershellistäkin, mutta se on vain alias Get-Process CmdLetille, jolla saadaan helposti selville, mitä prosesseja järjestelmässä on käynnissä (alla typistetty tuloste):
> Get-Process
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
136 8 6428 8084 569 0.08 916 bash
26 3 1496 2272 16 0.02 1560 cmd
57 7 1096 5852 57 0.03 2144 firefox
0 0 0 4 0 0 openvpn
88 7 988 3668 50 0.02 2676 openvpnserv
34 3 500 2332 14 0.00 4940 openvpnserv
562 27 151992 161440 615 4.27 2388 powershell
Jos prosessin nimi on jo tiedossa, voidaan se antaa -Name -parametrilla - huomaa, että .exe jätetään pois lopusta:
Cobbler autodetect system name
Cobblerissa on eräs varsin heikosti dokumentoitu ominaisuus, jonka avulla on mahdollista selvittää, mikä kyselyn tekevän koneen nimi Cobblerissa on. Tästä on hyötyä esimerkiksi Windowsin bootstrappauksessa, jotta saadaan noudettua oikeaan Cobbler System-olioon liittyvä Unattended.xml -tiedosto. Linuxien tapauksessa tähän kikkailuun ei ole tarvetta, koska Cobblerin parametrit välittyvät käyttöjärjestelmän asentimelle suoraan kickstart- tai preseed tiedoston mukana.
Itse ominaisuus on erittäin yksinkertainen käyttää, kunhan muistaa ajaa sen siltä koneelta, jonka System name halutaan tietää:
Cobbler templatet
Käytämme työasemien ja osin myös palvelimien provisioinnissa Cobbleria. Se on vahvimmillaan juuri fyysisten laitteiden provisionnissa, vaikka perustason tuki myös virtuaalikoneiden provisioinnille löytyykin. Cobbler nitoo yhteen lukuisia eri palveluita (dhcp, dns, tftp) Python-koodin avulla, joten aivojen vääntäminen sen vaatimiin asetuksiin vie aikansa. Cobblerin perusdokumentaatio on RedHatille tyypilliseen tyyliin varsin hyvää, mutta ongelmiin joutuu helposti, kun halua tehdä jotain virallisen dokumentaation ulkopuolelta. Esimerkiksi Cobblerin web-API on dokumentoitu varsin heikosti, lähinnä tässä Wiki-artikkelissa. Tässä ja tulevissa blogikirjoituksissa pyritään paikkaamaan Cobblerin dokumentaation puutetta.
Hieran debuggauksesta
Toisinaan Puppet-koodissa on tarve tehdä haku Hierasta, mutta se ei toimi odotetulla tavalla. Näissä tapauksissa auttaa “puppet lookup”-komento:
$ puppet lookup --node www.domain.com --explain bacula::filedaemon::backup_files
Data Binding "hiera"
Found key: "bacula::filedaemon::backup_files" value: [
"/etc",
"/var/lib/puppet/ssl",
"/var/backups/local"
]
Erikoista kyllä, tämä komento löytää ainoastaan ne Hieran hierarkian tasot, jotka perustuvat faktoihin:
---
:backends:
- yaml
:hierarchy:
- "nodes/%{::trusted.certname}"
- "roles/%{::role}"
- "lsbdistcodename/%{::lsbdistcodename}"
- "osfamily/%{::osfamily}"
- "kernel/%{::kernel}"
- common
:yaml:
:datadir:
Yllä muuttuja role ei siis ole fakta, vaan se on oikeastaan parametri tai käytänne, joka määritetään noodin yaml-tiedostossa:
Windowsin järjestelmätiedostojen ylikirjoittaminen Puppetilla
Windowsin järjestelmätiedostoja ei useinkaan pysty muuttamaan käsin - tai Puppetilla - ilman niiden suojaustason alentamista. Ongelma on siinä, että järjestelmätiedostojen omistaja on usein (pseudo)käyttäjä “TrustedInstaller”, eikä edes administrator-tason käyttäjillä ole niihin kirjoitusoikeutta. Onneksi rajoitukset voi kiertää melko suoraviivaisesti käyttämällä takeown.exe -komentoa sekä puppetlabs/acl -moduulia. Alla on muokattu erästä Group Policyn XML-tiedostoa, jonka merkistökoodaus oli siinä määrin poikkeuksellinen, että sen lukeminen Rubyn reXML -kirjastolla ei onnistunut:
include ::acl
# Vaihda tiedoston omistaja
exec { 'takeown-Search.admx':
command => 'C:WindowsSystem32takeown.exe /f C:WindowsPolicyDefinitionsSearch.admx',
}
# Määritä uudet oikeudet
acl { 'Search.admx':
target => 'C:/Windows/PolicyDefinitions/Search.admx',
permissions => [
{ identity => 'Järjestelmänvalvojat', rights => ['full'] },
{ identity => 'SYSTEM', rights => ['full'] }
],
require => Exec['takeown-Search.admx'],
}
# Korvaa tiedosto
file { 'C:/Windows/PolicyDefinitions/Search.admx':
source => 'puppet:///modules/winpolicydefinitions/Search.admx',
require => Acl['Search.admx'],
}
Tästä prosessista kannattaisi muokata oma määritelty resurssinsa, tai jopa peräti oma tyyppinsä, mikäli sille löytyisi runsaasti käyttöä. Takeown-komentoon kannattaisi lisätä myös “unless”-parametri, jotta sitä ei ajeta turhaan joka kerta. Jos Execissä olisi “provider => ‘powershell’”, niin tarkistuksen voisi tehdä muutamin eri tavoin.
Windowsin paikallisten ryhmäkäytäntöjen muokkaus Puppetilla
Monia Windowsien asetuksia on perinteisesti muokattu ryhmäkäytänteillä (“Group Policy”). Vaikka ryhmäkäytänteiden teho onkin melko rajallinen, pystyy niillä tekemään yhtä ja toista. Microsoft on kuitenkin Powershell DSC:n kuitenkin siirtymässä tilan hallintaan perustuviin modernimpiin ratkaisuja, joten Group Policyt jäänevät lähivuosina historiaan.
Tästä huolimatta ryhmäkäytänteitä hyödynnetään yhä erityisesti Active Directory -toimialueiden (“domain”) kanssa silloin, kun halutaan standardisoida työasemien asetuksia. Myös Samba 4 tukee ryhmäkäytänteiden jakelua työasemille. Ryhmäkäytänteet eivät kuitenkaan vaadi Active Directoryn tai Samba 4:n käyttöä, sillä käytänteitä voidaan määrittää paitsi verkkoalueelle, myös paikallisesti (“Local Group Policy”). Käytänteet voidaan lisäksi jakaa käyttäjäkohtaisiin (“User policy”) ja tietokonekohtaisiin (“Machine policy”).
Powershelliä UNIX-ylläpitäjille, osa 12
Toisinaan tulee tarpeelliseksi etsiä yhdestä tai useammasta tiedostosta jotakin merkkijonoa ja tulostaa täsmäävä rivi sekä tiedosto, jossa se on, sekä rivinumero. GNU grepillä tämä onnistuu triviaalisti komennolla “grep -HN pattern”:
$ grep -Hn REXML *.rb
group_policy.rb:71: dFile = REXML::Document.new( File.new("#{dDir}\#{array[0][0]}.admx"))
group_policy.rb:72: eFile = REXML::Document.new( File.new("#{eDir}\#{array[0][0]}.adml"))
group_policy.rb:154: dFile = REXML::Document.new( File.new("#{dDir}\#{sys_tShort}.admx"))
group_policy.rb:155: eFile = REXML::Document.new( File.new("#{eDir}\#{sys_tShort}.adml"))
group_policy.rb:428: dFile = REXML::Document.new( File.new("#{dDir}\#{tShort}.admx"))
group_policy.rb:429: eFile = REXML::Document.new( File.new("#{dDir}\#{adml}"))
Sama homma onnistuu myös Powershellissä, mutta hieman vaikeammin:
Powershelliä UNIX-ylläpitäjille, osa 10
Windowsin käynnistyviin ohjelma- ja kirjastotiedostoihin liittyy paljon erilaista metatietoa, esimerkiksi ohjelman versionumero, julkaisija yms. Näiden metatietojen tarkastelu on toisinaan hyödyllistä, etenkin ohjelmistoja testattaessa. Alla OpenVPN:n bin -kansion sisältö kokonaisuudessaan:
PS C:Program FilesOpenVPNbin> Get-ChildItem
Directory: C:Program FilesOpenVPNbin
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 7.3.2016 16:40 1753440 libeay32.dll
-a--- 7.3.2016 16:40 226432 liblzo2-2.dll
-a--- 7.3.2016 16:40 123000 libpkcs11-helper-1.dll
-a--- 7.3.2016 16:40 465760 openvpn-gui.exe
-a--- 7.3.2016 16:40 965984 openvpn.exe
-a--- 7.3.2016 16:40 65888 openvpnserv.exe
-a--- 7.3.2016 16:40 396640 ssleay32.dll
Metatiedot on tallennettu tiedosto-objektin VersionInfo-parametriin - alla tarkastellaan openvpn.exe -tiedoston metatietoja:
Powershelliä UNIX-ylläpitäjille, osa 11
Windowsin tuoteavain (“Product Key”) löytyy esiasennetuissa koneissa usein koneen pohjasta, mutta entäpä jos Windows onkin jälkiasennettu, tai koneen pohjassa oleva tarra ei edustakaan todellisuutta? Jos tällainen kone soseutuu, ei tuoteavainta löydy tietenkään mistään fyysisestä paikasta, ja tuloksena on kone ilman Windowsia; tämä voi toki olla toivottavakin asiaintila, mutta lähdetään siitä oletuksesta, ettei näin ole.
Tuoteavain on onneksi tallennettu Windowsin rekisteriin, mistä sen saa otettua talteen useilla eri tavoilla. Koska tässä blogissa keskitytään automaatioon ja Powershellin, mitkään graafiset kikkareet eivät luonnollisestikaan tule kyseeseen. Onneksi homma hoituu myös alla olevalla Powershell-skriptillä (lähde):
Powershelliä UNIX-ylläpitäjille, osa 9
Toisinaan on tarpeen lisätä tekstitiedoston loppuun rivejä. UNIX:ssa tämä onnistuu helposti echo-komennolla:
$ echo matti >> vpn.pass
$ echo salasana >> vpn.pass
$ cat vpn.pass
matti
salasana
Sama onnistuu Powershellissä, mutta ei suinkaan Write-Host -komennolla, joka olisi echo-komennon lähin vastine, vaan Add-Content -komennolla:
> Add-Content vpn.pass -Value matti
> Add-Content vpn.pass -Value salasana
> Get-Content vpn.pass
matti
salasana
Toinen melko yleinen tarve on tiedostojen lataaminen verkosta suoraan komentoriviltä. UNIX:ssa tämä onnistuu helpoiten wget-komennolla: