mayho33
Goto Top

Immer wiederkehrende Befehle in einer XML oder einem Object speicher

Hallo Community!

Ich stehe wieder mal vor einem "unlösbaren" Problem und hoffe auf eure Hilfe!

Seit kurzem beschäftige ich mich mit Powershell und frage mich ob man immer wiederkehrende Commandos nicht etwa in einer XML speicher kann,

(z.B. sowas: $ar = get-process -name $KillDelayed | %{ $_.closemainwindow() } -ErrorAction SilentlyContinue ; $myError = $null ; $myError = $?
oder ein Command für Logging, usw...)

und dieses Commando aus der xml zur Laufzeit ausliest und ausführt.

Warum ich das tun möchte: Speziell beim Logging sehe ich, dass ich die Commands sehr oft brauche in verschiedenen eigenen Cmdlets. Will ich also eine Änderung machen, muss ich das in allen cmdlets tun in denen ich z.B. in ein Logfile schreibe.
Nun dachte ich, dass dass Command an einem zentralen Ort gespeichert doch viel einfacher wartbar wäre und ich im cmdlet nichts ändern muss.

Hat jemand eine Idee wie ich das umsetzen könnte? Stehe voll am Schlauch, nicht mal ein Ansatz.

Danke für eure Hilfe!

Mayho

Content-Key: 226337

Url: https://administrator.de/contentid/226337

Printed on: April 19, 2024 at 16:04 o'clock

Member: colinardo
colinardo Jan 10, 2014 updated at 17:21:27 (UTC)
Goto Top
Hallo Mayho,
du kannst dir die Funktionen im Powerhell-Profil hinterlegen, dann hast du sie in jedem Powershell-Script zur Verfügung stehen:
http://www.windowspro.de/wolfgang-sommergut/powershell-konfigurieren-mi ...
darin kannst du dir dann z.B. eine Funktion zum Logging etc. anlegen
Function Log($text, $file){
...
...
}
Grüße Uwe
Member: mayho33
mayho33 Jan 10, 2014 at 17:21:28 (UTC)
Goto Top
Hi colinardo!

Danke für deine Antwort!

Leider ist das nicht ganz das was ich wollte oder ich habe es falsch verstanden.

Eine etwas genauere Erklärung:

Wir basteln gerade an der Umsetzung eines InstallScripts in Powershell für SCCM2012. Das ganze soll modular aufgebaut sein, sprich, für jede Function ein eigenes cmdlet. Das ganze Set wird dann per MSI auf dem Zielclient hier installiert: "C:\Windows\System32\WindowsPowerShell\v1.0\Modules" damit die Functions global verfügbar sind.

Es werden also in etwa 15 cmdlets sein die via einem "Doing.ps1" angesprochen werden. jedes cmdlet schreibt über ein Write-Log-cmdlet ins Logfile.
Da das logfile natürlich schön und gleichmäßig formatiert sein soll kommen einige "Aufrufe" zusammen. Und das aus fast allen cmdlets die wir erstellen. Sollte also eine Änderung in der Formatierung des LogFiles anstehen, müssten wir fast alle cmdlets angreifen und diese Änderung nachziehen.

Meine Idee war also eine XML in der die Command für das Logging hinterlegt sind (z.B. WriteLog -CreationSteps Create, WriteLog -CreationSteps Progress -LogText "irgendwas", WriteLog -CreationSteps Finish, usw....)

(Ich dachte da mehr an Objects usw., sprich das XML auslesen in ein Object speichern, sodass es nicht mehr reiner Text ist sondern die Parameter wieder als solche erkannt werden. Write-Log -CreationSteps......)

das wird mitunter 10-12 mal mit jeweils anderen Parametern oder Strings gemacht je nach Vorraussetzung und cmdlet.
Mühsam wenn z.B. zwischen den einzellnen Zeilen eine Leerzeile eingebaut werden soll, oder der TimeStamp anders formatiert werden soll, oder, oder, oder.

Wäre das in einer XML hinterlegt würde der Aufruf sich nicht ändern. Es bracht nur die XML editiert zu werden und schon schauts anders aus.

Das mit den Profiles geht nicht. Der SCCM führt Scripte usw. immer als System aus der hat im Pronzip kein Profil und s müsste ja schon angepasst sein bevor die Installation anläuft. Bei neu aufgesetzen Clients oder solche die gerade aufgesetzt werden leider nicht möglich.

Trotzdem Danke!

Ne andere Idee eventuell??

Grüße Mayho!
Member: colinardo
colinardo Jan 10, 2014, updated at Jan 11, 2014 at 13:44:08 (UTC)
Goto Top
Habe dazu vor einiger Zeit mal einen Beitrag zum Speichern und Auslesen von Einstellungen aus einer XML-Datei geschrieben, eventuell hilft dir das bei deinem Projekt weiter:
Powershell: Werte aus einer XML-Datei auslesen und wieder darin speichern

Grüße Uwe
Member: mayho33
mayho33 Jan 11, 2014 updated at 10:07:23 (UTC)
Goto Top
Hi!

Danke für den ausführliche Beitrag, aber das XML auslesen ist keine Problem.

Ich möchte die Werte aus der XML wieder brauchbar machen. Speichert man einen Wert in der XML (etwa so: XML-Property: Loggoing_StopProc, Value: WriteLog -CreationSteps Progress -LogText "irgendwas") und lese diesen dann in PS in z.B. ein $Value ein, wird er anschließend natürlich nicht mehr als Aufruf einer Function erkannt, ist ja nun ein String. Den umzuwandeln in was Verwertbares habe ich bisher nicht geschafft.

Ich werde es aber auf die 2 Varianten versuchen:

a)
Alle cmdlets übergeben ihre Loggings an eine "Zwischen-Funktion" in der die Formatierung vorgenommen wird. gibt es Änderungen in der Formatierung muss ich das wenigstens nur mehr in einem Cmdlet machen.

Etwa so:

Aufruf im übergeordneten Ps1 = Stop-Procs -ProcessList "proc1,proc2,proc3,..."
in Stop-Procs wird für jeden beendeten Process nun Format-Log -Function Stop_Proc -LogText "stopping process <Name> successfully" aufgerufen
Format-Log baut den eigentlichen Eintrag so zusammen und formatiert ihn, dass er ins Logfile eingetragen werden kann und diese auch gut lesbar ist. Anschließend wird Write-Log mit den entsprechenden Doings aufgerufen und schreibt das Logfile.

Das ganze gibt es dann auch für alle anderen cmdlets. Jedes gibt unformatiert seinen Log an Format-Log weiter. und dieser arbeitet den String entsprechend um.

Ist zwar nicht ganz das was ich ursprünglich machen wollte, weil noch ein ZwischenSchritt drinnen ist und das verlangsamt den Ablauf, aber es ist praktikabel und besser wartbar.

b)
in der XML werden enthält das Property nur mehr das bereits formatierte Value für den LogText. Diesen lese ich in eine Variable ein und übergebe ihn an Write-Log

Was in beiden Varianten halt nicht funktioniert ist z.B. dass ich das ganze Command ändere an einem zentralen Ort.
Etwa so, dass ich z.B. das Property1 von mir aus lösche. Lese ich nun den Folder des XML entsprechend der Function in ein Array ist diese Function halt nicht mehr das. Alles andere ist sehr statisch. Wollte ich vermeiden. Siehe Bsp:

Folder:Stop-Proc:
Property1: Value = WriteLog -CreationSteps Create
Property2: Value = -CreationSteps Progress -LogText "irgendwas"
...
...
Property3: Value =WriteLog -CreationSteps Finish
...
...
Folder: Uninstall
...
...
Folder Install
...
...


Danke trotzdem für deine Unterstützung und Hilfe! Dein Beitrag bekommt ein dickes +

Falls doch noch jemand einen Tipp hat für mich wie ich das so umsetzen könnte wie ich das Anfangs erklärt habe, würde mich das freuen!

lg

Mayho
Member: colinardo
Solution colinardo Jan 11, 2014, updated at Jan 26, 2014 at 22:59:17 (UTC)
Goto Top
Zitat von @mayho33:
Ich möchte die Werte aus der XML wieder brauchbar machen. Speichert man einen Wert in der XML (etwa so: XML-Property:
Loggoing_StopProc, Value: WriteLog -CreationSteps Progress -LogText "irgendwas") und lese diesen dann in PS in z.B. ein
$Value ein, wird er anschließend natürlich nicht mehr als Aufruf einer Function erkannt, ist ja nun ein String. Den
umzuwandeln in was Verwertbares habe ich bisher nicht geschafft.
Also einen String kannst du so wieder in einen Scriptblock wandeln, das wäre kein Problem:
function Convert-StringToScriptBlock {
  param(
  [parameter(ValueFromPipeline=$true,Position=0)]
  [string] $string
  )
 $sb = [scriptblock]::Create($string)
 return $sb
}
# Konvertiere einen String zu einem Scriptblock
$code = echo "Write-host 'Das ist ein Test'" | Convert-StringToScriptBlock  
# führe den Code aus
&$code
Grüße Uwe
Member: mayho33
mayho33 Jan 26, 2014 at 22:59:01 (UTC)
Goto Top
Hi Uwe!

Sorry, dass ich mich so lange nicht gemeldet habe, War etwas im Stress.

Danke für diesen echt hilfreichen Tipp! Der ist perfekt!!

Ab jetzt bist du wohl mein Hero! face-wink

lg

Mayho

PS: eventuell hast du hier auch sowas geniales parat? ( Start-Process gibt tlw. keinen ReturnCode aus (PowerShell) )