Úprava nastavení programů při zachování osobních parametrů

Pozadí

V jedné zdravotnické organizaci se zaváděla řešení založená na PACS serverech Orthanc a DICOM klientovi Radiant. Během nastavení se zjistilo, že každý DICOM klient musí být popsán na PACS serverech následujícím způsobem:

  • Jméno klienta
  • AE-jméno (musí být unikátní)
  • TCP port, který se automaticky otevírá na straně klienta a přijímá DICOM vyšetření od PACS serveru (tj. server je jakoby tlačí směrem k klientovi – zahájí spojení jako první)
  • IP adresa

Po nastavení klientů Radiant jsme dostali následující informace k zamyšlení – u každého klienta nastavení softwaru s výše uvedenými parametry vedlo k naplnění souboru pacs.xml, který se nacházel v profilu uživatele (cesta: %APPDATA%RadiantViewerpacs.xml). Přičemž konfigurace jednoho klienta se lišila od druhého minimálně dvěma parametry (AE-jméno mělo každé jiné, port byl většinou stejný, kromě terminálových klientů, které pracovaly na stejném serveru – tam se také musely porty nastavovat různě).

Příklad souboru pacs.xml podle odkazu:

Přibližně půl roku bylo vše v pořádku, systém fungoval… a zde nás přepadly "úskalí kameni»:

  • Musíme zavést několik nových PACS serverů, které nahradí staré (kde už začínalo docházet místo na discích). PACS servery ve virtuálních strojích, ale o tom teď nemluvíme;
  • Musíme nějak centralizovaně změnit unikátní konfigurace (dvěmi odlišnými parametry) na 200 strojích (jejich počet se pravidelně zvyšoval);
  • Vzhledem k tempu růstu objemů vyšetření je potřeba řešení, které není jednorázové, ale převoditelné a pravidelné (například jednou za 3-5 měsíců).

Níže uvedené řešení.

Výběr nástrojů pro řešení úkolu

Zpočátku jsme se pokoušeli najít nějaké řešení, které na straně klienta měnilo soubor pacs.xml a vnášelo do něj změny v seznamu PACS serverů, aniž by se dotýkalo nastavení AE-jména a TCP portu. Windows klienti byly tehdy na bázi jak Windows XP, tak Windows 7 – proto jsme se pokoušeli napsat něco na bázi VBScript. Ale bohužel – tuto úlohu se nám nepodařilo zvládnout, vzhledem k naprosté absenci zkušeností v psaní něčeho složitého a komplexního v tomto jazyce. Pokusy o nalezení a přepsání také nebyly úspěšné (tady je třeba poznamenat, že už jsem měl v hlavě jiný plán, takže jsem se s VBScript už díval víc než 3-4 hodiny).

Nakonec jsem se zastavil na následujícím řešení:

  • Sběr všech souborů pacs.xml na jednom místě na jakémkoliv serveru v síťovém zdroji pomocí skupinové politiky;
  • Změna souborů hromadně (máme zkušenosti s řešením takových úloh – s využitím Perl);
  • Také pomocí skupinových politik aktualizovat nastavení klientů.

Sběr souborů pomocí skupinové politiky

Nejjednodušší část – při vstupu klienta do svého profilu s jeho právy se spustí určité .bat soubor, ve kterém je uvedeno:

echo off
If exist %APPDATA%RadiantViewerpacs.xml copy %APPDATA%RadiantViewerpacs.xml srv.test.localpconfigs$pacs-%COMPUTERNAME%-%USERNAME%.xml

Tímto způsobem se na serveru ve skrytém zdroji budou shromažďovat soubory pacs.xml, jejichž názvy obsahují informace o tom, z jakého počítače a od jakého uživatele byl tento konfigurační soubor zkopírován.

Nejtěžší bylo počkat, až tato politika proběhne u všech uživatelů.

Zmnaění konfigurací pomocí Perl skriptu

Budeme potřebovat Active Perl pro Windows od společnosti ActiveState, a také modul XML::Writer, který lze nainstalovat pomocí příkazu ppm install XML-Writer.

Sám skript se ukázal jako docela jednoduchý:

use XML::Writer;
 
# Otevřeme složku s reporty, zpracujeme seznam (odstraníme nadbytečné):
	$report_dir = "C:Perl64WORKPACS-xml3";
	opendir(DIR, "$report_dir") or die "Nemohu otevřít složku s reporty!";
	@report_files = readdir DIR;
	shift (@report_files); # odstraníme tečku z prvků pole (.)
	shift (@report_files); # odstraníme dvě tečky z prvků pole (..)
#	print "@report_files";
	closedir(DIR);
 
# Začínáme zpracovávat soubory - po jednom. Je potřeba načíst parametr AET a číslo portu do proměnných.
foreach $analiz_file (@report_files) 
{
	$full_path_to_file="C:Perl64WORKPACS-xml3".$analiz_file;
	open (INFO, $full_path_to_file);
 
	while ($line = )
	{
		# Proměnné $aet a $port obsahují jedinečné údaje pro každý XML soubor:
		my ($other1, $aet, $other2, $port, $other3) = split "/", $line, 5;
		# Pokud se setkáme se řetězcem listener - tak jsme došli na potřebný řádek a můžeme vytvořit nový XML:
		if ($other1 =~ 'listener')
			{
				# Vytváříme nový XML s potřebnými poli a údaji:
				my $writer = XML::Writer->new(OUTPUT => 'self', DATA_MODE => 1, DATA_INDENT => 2, );
				$writer->xmlDecl('utf-8');
				$writer->startTag('pacs');
				$writer->startTag('listener', ae => $aet, port => $port);
				$writer->endTag();
				$writer->startTag('hosts');
				$writer->startTag('host', name => 'MRT', ae => 'ORTHANC', ip => 'XX.YY.214.17', ts => '1.2.840.10008.1.2.1', port => '4242', maxassoc => '1', allpres => '0', search => '1', protocol => '1', searchcharset => '', wildcards => '3', carets => '0');
				$writer->endTag();
				$writer->startTag('host', name => 'KT', ae => 'ORTHANC2', ip => 'XX.YY.215.253', ts => '1.2.840.10008.1.2.1', port => '4242', maxassoc => '1', allpres => '0', search => '1', protocol => '1', searchcharset => '', wildcards => '3', carets => '0');
				$writer->endTag();
				$writer->startTag('host', name => 'R', ae => 'ORTHANC3', ip => 'XX.YY.215.252', ts => '1.2.840.10008.1.2.1', port => '4242', maxassoc => '1', allpres => '0', search => '1', protocol => '1', searchcharset => '', wildcards => '3', carets => '0');
				$writer->endTag();
				$writer->startTag('host', name => 'KT-20180501-20180831', ae => 'ORTHANC4', ip => 'XX.YY.215.251', ts => '1.2.840.10008.1.2.1', port => '4242', maxassoc => '1', allpres => '0', search => '1', protocol => '1', searchcharset => '', wildcards => '3', carets => '0');
				$writer->endTag();
				$writer->startTag('host', name => 'KT-20180901-20181130', ae => 'ORTHANC5', ip => 'XX.YY.215.250', ts => '1.2.840.10008.1.2.1', port => '4242', maxassoc => '1', allpres => '0', search => '1', protocol => '1', searchcharset => '', wildcards => '3', carets => '0');
				$writer->endTag();
				$writer->endTag('hosts');
				$writer->startTag('presets');
				$writer->endTag();
				$writer->startTag('lastsearch', dt => '4', mfid => '1048592');
				$writer->endTag();
				$writer->endTag('pacs');
 
				# Umístíme hotový XML do proměnné:
				my $xml = $writer->end();
				# Připravíme soubor k přepsání:
				$rewritexml = $full_path_to_file;
				# Přepisujeme XML soubory novými údaji:
				open (NEWXML, "> $rewritexml");
				print NEWXML $xml;
				close (NEWXML);
			}
	}
 
}

Princip jeho fungování:

  • Otevíráme katalog, ve kterém máme shromážděnými konfiguracemi pacs.xml od klientů, a umisťujeme seznam souborů do pole skalarů (@report_files);
  • V cyklu zpracováváme jeden soubor po druhém a čteme jej po řádcích;
  • Pomocí split rozdělujeme každý řádek na 5 částí, používající uvozovky jako oddělovač;
  • Najdeme řádek se slovem listener a uložíme do dvou proměnných, unikátní pro každý soubor, data (AE-jméno klienta a číslo TCP-portu);
  • Poté jednoduše vytváříme nový XML-soubor, zapisujeme do něj unikátní parametry a dále vkládáme potřebný počet PACS-serverů s jejich parametry – tzn. to, kvůli čemu bylo vše zahájeno)
  • Přepisujeme nový XML-soubor na starý.

Musím podotknout, že ve skutečnosti tento skript nepoužívám zcela automaticky – v podstatě kopíruji shromážděné konfigurace do samostatného katalogu a pak spouštím skript, abych je změnil všechny najednou. Následuje výběrová kontrola – a konfigurace lze zase rozdělit po strojích.

Distribuce změněných pacs.xml souborů mezi klienty

Nejjednodušší, co mě napadlo – provést změny v již fungujícím .bat souboru, který sbírá konfigurace z klientů, a přidat řádek:

If exist %APPDATA%RadiantViewerpacs.xml copy /Y srv.test.localpconfigsnew$pacs-%COMPUTERNAME%-%USERNAME%.xml %APPDATA%RadiantViewerpacs.xml

Výsledný .bat soubor vypadá takto:

@echo off
If exist %APPDATA%RadiantViewerpacs.xml copy %APPDATA%RadiantViewerpacs.xml srv.test.localpconfigs$pacs-%COMPUTERNAME%-%USERNAME%.xml
If exist %APPDATA%RadiantViewerpacs.xml copy /Y srv.test.localpconfigsnew$pacs-%COMPUTERNAME%-%USERNAME%.xml %APPDATA%RadiantViewerpacs.xml

Závěr

Takové tedy "na koleně" řešení. Vyzkoušeli jsme to už dvakrát (v září 2018 a v únoru 2019), zatím let normální. Samozřejmě neaktualizuje 100% klientů, ale blízko této hodnoty – ostatní doděláváme na dálku. Skript podle odkazu.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster