Anzeige

Am Puls von Microsoft

Anzeige

[gelöst] Visual Basic Script in Powershell umwandeln

Status
Dieses Thema wurde gelöst! Lösung ansehen…
Für weitere Antworten geschlossen.

edv.kleini

Win11 Registry-Fummler
Mal zur Erklärung

Ich bin dabei alle Visual Basic Scripte in Powershellscripte umzuwandeln.
Von den 43 Dateien hat das auch ohne Probleme bis auf den zweien im Anhang geklappt.
Worum es mir hier geht...
Ich habe auf Laufwerk E:\Desktophintergrund\Bisherige_Desktop_Hintergrundbilder
momentan 1250 Bilder als Diashow mit 30 Sekunden-Intervall. (Ja...Intervallzeit ist ja einstellbar.)
Einige Kunden und Freunde haben das auch und sind total begeistert.
Irgendwann kam einer auf die Idee und fragte danach, wo welches Bild denn herstammt
bzw. was es darstellt, Örtlichkeit usw.
Dafür habe ich eine Textdatei geschrieben, wo zu jedem Bild, soweit möglich Informationen drinstehen.
Das Visual Basic Script schaut also erstmal nach, welches Bild gerade aktiv geladen ist.
Dann öffnet es den Windows Explorer mit meiner Textdatei und springt als Beispiel auf Bild 435.
Da stehen dann in der entsprechenden Zeile die Informationen.
So... und das Ganze umgewandelt als Powershellscript.... Na prost Mahlzeit...

Wer die Zeit und Muße hat, kann mir mal bitte helfen.
 

Anhänge

  • Show_Info_Diashow_Picture.zip
    51,8 KB · Aufrufe: 83
  • Bild1.JPG
    Bild1.JPG
    118,4 KB · Aufrufe: 77
Anzeige
Der letzte Teil des Visual Basic Scriptes ganz unten ist ja noch relativ leicht umzusetzen
Invoke-item "E:\Desktophintergrund\Liste_aller_Bilder.txt"

$obj = New-Object -com Wscript.Shell
sleep -s 2
$obj.SendKeys("^f")
sleep -m 1200
$obj.SendKeys (""& sContents &"")
Sleep -m 600
$obj.SendKeys ("{ENTER}")
Sleep -m 600
$obj.SendKeys ("%{F4}")

bzw.

Invoke-item "E:\Desktophintergrund\Liste_aller_Bilder.txt"

$obj = New-Object -com Wscript.Shell
sleep -s 2
$obj.SendKeys("^f")
sleep -m 1200
$obj.SendKeys (""& sContents &"")
Sleep -m 600
$obj.SendKeys ("{ENTER}")
Sleep -m 600
$obj.SendKeys ("{TAB}")
Sleep -m 600
$obj.SendKeys ("{TAB}")
Sleep -m 600
$obj.SendKeys ("{TAB}")
Sleep -m 600
$obj.SendKeys ("{TAB}")
Sleep -m 600
$obj.SendKeys ("{ENTER}")

Der Unterschied besteht einfach darin, ob man das alte Notepad (aus dem FoD Package) (1. Eintrag bzw. Spoiler)
oder die "neue" Notepad.exe aus dem C:\Program files\WindowsApps Verzeichnis nutzt (2. Eintrag bzw. Spoiler)
Wie gesagt... der unterste Teil des Scriptes ist nicht das Problem.
 
Zuletzt bearbeitet:
Ein Teil vom Anfang zum Ermitteln des Hintergrundbilds könnte so aussehen:
Code:
$USERSID1= Get-LocalUser -Name $env:USERNAME | Select sid
$USERSID1a="$USERSID1"
$USERSID2= $USERSID1a.Substring(6, ($USERSID1a.length-7))
$hk= "Registry::HKEY_USERS\"
Get-ItemPropertyValue $hk$USERSID2'\Control Panel\Desktop' -Name WallPaper
 
Problem ist dabei aber nur, das es nichts mit den Reg-Eintrag Wallpaper zu tun hat, sondern mit dem
Reg-Binary Eintrag "Transcoded Wallpaper" und erst ab der 140. Stelle kommt der Name
z.B. Desktop_421.jpg. Auch dieser komplette Eintrag muss erst von Reg-Binary in Klartext umgewandelt
werden und dann als Variabale (reduziert auf den Datei-Namen) an die Text-Datei ausgegeben werden.
Über den Wcriptshell Befehl lassen sich auch Sprungziele (Sendkey Befehle) in Powershell ausführen.
Skorpion68 arbeitet schon daran...
 
Skorpion68 arbeitet schon daran...
Leider bekomme ich immer noch nicht die Variable des verwendeten Hintergrundes in die Suche, um dann folgende Massage Box anzuzeigen:

Desktop_436.png (Zum Vergrößern anklicken)

Das Ergebnis kann sich so doch sehen lassen.

Gebe ich aber anstatt der Variable $Image direkt Desktop_436.jpg in folgenden Befehl ein, dann funktioniert es wie es soll:

Code:
$Info = Get-ChildItem -Path 'E:\Desktophintergrund\Liste_aller_Bilder.txt' | Select-String -Pattern $Image | Select-Object -ExpandProperty Line
 
Steht bei dir im "Transcoded Wallpaper" der Dateiname direkt drin? Im VBS sehe ich keinen Code, welcher da was umwandelt.
 
Doch, natürlich steht ein Wert bei einer DIA-Show TranscodedWallpaper drin.
Aber, der Wert ist eine Reg-Binary.
Über das Visual Basic Script wird es in einen Klartext umgewandelt und ab der 140. Stelle
als Variable in einen Klartext ausgegeben.
Fett gemachte Zeilen GetBinaryValue und For i = 140 to Ubound(sValue und folgend).
In den Zeilen findet die Umwandlung von Regbinary in Klartext statt.
Und mal ehrlich... so groß ist das Script nicht.


Const HKCU = &H80000001 'HKEY_CURRENT_USER

sComputer = "."

Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" _
& sComputer & "\root\default:StdRegProv")

sKeyPath = "Control Panel\Desktop\"
sValueName = "TranscodedImageCache"
oReg.GetBinaryValue HKCU, sKeyPath, sValueName, sValue

sContents = ""

For i = 140 To UBound(sValue)
vByte = sValue(i)
If vByte <> 0 And vByte <> "" Then
sContents = sContents & Chr(vByte)
End If
Next



dim mystring
mystring= ""& sContents &""

if mystring = "" then
wscript.quit
end if

Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run("explorer.exe E:\Desktophintergrund\Liste_aller_Bilder.txt")

Wscript.Sleep 1800
WshShell.SendKeys ("^f")
Wscript.Sleep 1200
WshShell.SendKeys (""& mystring &"")
Wscript.Sleep 600
WshShell.SendKeys ("{ENTER}")
Wscript.Sleep 600
WshShell.SendKeys ("%{F4}")

In den ersten Zeilen wird einfach nur fest gelegt, welcher Registrypfad den entsprechenden Werten und Variablen
zugeordned wird.
Der Reg-Binary-Wert von Transcoded Wallpaper wird danach ausgewertet und ab der 140. Stelle in
Klartext umgewandelt und das in die mystring Variable übertragen.
Im unteren Abschnitt wird über den Windows Explorer die Datei Liste_aller_Bilder.txt geöffnet.
Immer noch in Visual Basic drin
wird jetzt über den Sendkey Befehl zuerst über STRG und F die Suchfunktion angewählt.
In die Suchzeile wird über den Sendkey Befehl jetzt die Variable "mystring" mit dem
Namen der Bild-Datei eingefügt. Über den Sendkey Befehl "Enter" wird mit Return oder Enter bestätigt.
Dadurch wird in der Datei Liste_aller_Bilder.txt automatisch in die Zeile gesprungen, wo die Infos zu dem
aktuellen Bild der Dia-Show stehen. Das ist im Grunde eigentlich alles.
Einen Unterschied macht momentan noch, welche Notepad.exe man nutzt.
Aber dafür habe ich auch Wege gefunden um das zu unterscheiden.
Es geht um die Notepad.exe im FoD-Package oder als Modern App aus dem C:\Programme\WindowsAPPs
Verzeichnis. Diese beiden Notepad.exe ( n ) unterscheiden sich nämlich in der Annahme von Sendkey Befehlen.
Der Aufruf der Liste_aller_Bilder.txt geschieht in einem Powershell-Script über den invoke Befehl.
Sendkey und sleep Befehle sind ähnlich.
Aber der Anfang des Scriptes mit der Umwandlung des Regbinarys und der Aufbröselung des Dateinamens ist momentan in Powershell noch nicht gelöst.
Messagebox ist zwar schön und gut aber...
Und genau darauf kommt es mir aber an:

Der Name der Datei des aktuellen Hintergrundbildes als Variable (Mystring) gesetzt...
den Rest mache ich dann in Powershell so.

$obj = New-Object -com Wscript.Shell
Invoke-item "E:\Desktophintergrund\Liste_aller_Bilder.txt"


sleep -s 2
$obj.SendKeys("^f")
sleep -m 1200
$obj.SendKeys(""& mystring &"")
Sleep -m 600
$obj.SendKeys("{ENTER}")
Sleep -m 600
$obj.SendKeys("%{F4}")


So, ich hoffe ich habe genug erklärt?!?
 
Zuletzt bearbeitet:
Aber der Anfang des Scriptes mit der Umwandlung des Regbinarys und der Aufbröselung des Dateinamens ist momentan in Powershell noch nicht gelöst.
Da kann ich dir weiterhelfen und habe es auch wie folgt getestet:

img0.png (Zum Vergrößern anklicken)

Das PowerShell-Script sieht jetzt wie folgt aus:

Code:
$Value = (Get-ItemProperty -Path 'HKCU:\Control Panel\Desktop').TranscodedImageCache
$ImagePath = [System.Text.Encoding]::Unicode.GetString($Value)
$Image = Split-Path $ImagePath -Leaf
$obj = New-Object -com Wscript.Shell
Invoke-item "E:\Desktophintergrund\Liste_aller_Bilder.txt"

sleep -s 2
$obj.SendKeys("^f")
sleep -m 1200
$obj.SendKeys($Image)
sleep -m 600
$obj.SendKeys("{ENTER}")
sleep -m 600
$obj.SendKeys("%{F4}")

Messagebox ist zwar schön und gut aber...
Ja ich weiß, du müsstest die Datei Liste_aller_Bilder.txt ändern, sodass für jedes der 10.000 Bilder nur eine Zeile besteht, um die Massagebox wie in Beitrag #5 dargestellt anzeigen zu lassen.

Leider bekomme ich immer noch nicht die Variable des verwendeten Hintergrundes in die Suche,
Was lange währt, wird endlich gut, denn ich habe eine Lösung gefunden, wie die Variable $Image doch noch angenommen wird. Belasse es hier aber bei dem o. g. Script, da die Datei Liste_aller_Bilder.txt bestimmt auch in ANSI und nicht in UTF8 gespeichert wurde, sodass eventuell die Umlaute nicht korrekt angezeigt werden.
 
@skorpion68
Du bist unschlagbar.
Ich danke Dir für Deine Hilfe.
Man sieht mal wieder mit Geduld und Spucke klappt es!
Ich bin halt noch nicht so ganz bewandert in Powershell.
Das VBScript hat auch so einige Anläufe benötigt, bis es funktioniert hat..
Auch die sleep-Zeiten sind immer so eine Sache, da sehr alte Rechner mehr Zeit brauchen.
Egal ob nun bei Visual Basic oder bei Powershell...
Da ein gesundes Mittelmaß zu finden geht auch nur über try and error.
Macht man das Ganze mit zu kurzen Sleep-Zeiten, verhaspelt sich so manch alte Kiste
und das Script hängt irgendwo "inne Seile". Zu lange Sleep-Zeiten fangen dann irgendwann an zu nerven.
 
Zuletzt bearbeitet:
Habe jetzt mal ne doofe Frage, MS will ja angeblich VBS-Scripte aus Windows 11 entfernen. Ich habe z.B. eine Soundwiedergabe per VBS ..
Code:
dim fname
 set objVoice=createobject("sapi.spvoice")
' Der Satz in den Klammern wird über die Sprachausgabe ausgegeben!
' Die Anführungszeichen müssen stehen bleiben.
 objvoice.speak ("Hallo Micha, dein Computer ist jetzt bereit")
.. damit ich z.B. bei VMs, die im Hintergrund laden, höre, wann diese bereit sind.
Lässt sich sowas denn überhaupt unter PowerShell realisieren ?
 
Haste ´ne PN @MSFreak

Weil es sonst wieder nur Mecker gibt und ich kenne die anderen Leser hier!
Wenn denen eine Lösung nicht gefällt oder in den Kram passt, wird man direkt verketzert und verleumdet.
 
Schaut mal hier rein


oder
 
Zuletzt bearbeitet:
Na zumindest bin ich Dank Skorpion68 mal mit meinen Scripten durch.
Ich habe jetzt meine 101 cmd (Batchdateien), vbscripte und Powershellscripte fertig.
In Abhängigkeit ob WMIC, VBSCript installiert ist oder nicht sind
die Dateien jetzt alle so ausgelegt, dass sie zuletzt in Powershell-Scripten ausgeführt werden.
Das heisst ich bin von nun an unabhängig mit meinen Computern von WMIC oder Visual Basic.
Was aber nicht heissen soll, dass ich es solange wie möglich nutzen werde.
Solange ich mit meinen Mitteln Visual Basic und WMIC so nach installiert bekomme,
und meine Dateien mit WMIC-Abfragen und Visual-Basic-Scripten funktionieren, solange nutze ich das auch.
 
Es ist zwar nur eine technische Spielerei, aber so langsam begreife ich wie Powershell tickt.
Die ganzen Kern-Daten eines Computers werden alle nur in / mit Powershell abgefragt!
Siehe Anhang

@echo off
cls
color f0
for /f "delims=" %%l in ('PowerShell -Command "(Get-WmiObject -class Win32_OperatingSystem).Caption"') do set meinbetriebssystem=%%l

for /f %%m in ('PowerShell -Command "Get-WmiObject -Namespace root\cimv2 -Class Win32_ComputerSystem | Select Domain | Format-Table -HideTableHeaders"') do set meinedomaene=%%m

for /f %%n in ('PowerShell -Command "Get-WmiObject -Namespace root\cimv2 -Class Win32_ComputerSystem | Select primaryownername | Format-Table -HideTableHeaders"') do set benutzername=%%n

for /f %%o in ('PowerShell -Command "Get-WmiObject -Namespace root\cimv2 -Class Win32_ComputerSystem | Select name | Format-Table -HideTableHeaders"') do set Computername=%%o

for /f %%p in ('PowerShell -Command "(Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion').CurrentBuild"') do set Buildnummer=%%p

for /f %%q in ('PowerShell -Command "(Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion').UBR"') do set erweiterung=%%q

for /f %%r in ('PowerShell -Command "(Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion').DisplayVersion"') do set Version=%%r

for /f %%s in ('PowerShell -Command "[System.Security.Principal.WindowsIdentity]::GetCurrent().User.value | Format-Table -HideTableHeaders"') do set userid=%%s

for /f %%t in ('PowerShell -Command "(Get-CimInstance Win32_operatingsystem).OSArchitecture"') do set architektur=%%t

cls
echo.
echo Die wichtigsten Kerndaten dieses Systems werden hier mit Powershell angezeigt.
echo.
echo Auf Ihrem Coumputer ist %meinbetriebssystem%, Version %Version% als %architektur% Betriebssystem installiert.
echo.
Echo Die momentane Buildnummer lautet %Buildnummer%.%erweiterung%.
echo.
echo Der Name dieses Computers lautet %Computername%.
echo.
echo Der Name der Arbeitsgruppe lautet %meinedomaene%.
echo.
echo Die User-ID des momentan angemeldeten Benutzers %Benutzername%
echo.
echo lautet %userid%.
echo.
pause
Einfach mal den Namen der Text-Datei in eine CMD umändern .txt in .bat oder .cmd.
Die Datei liegt auch fertig gezippt im Anhang.
 

Anhänge

  • Abfrage_Kerndaten.txt
    1,9 KB · Aufrufe: 68
  • Abfrage_Kerndaten.zip
    860 Bytes · Aufrufe: 57
Die wichtigsten Kerndaten dieses Systems werden hier mit Powershell angezeigt.
Habe die Befehle des Batch-Scripts Abfrage_Kerndaten.bat mal umgewandelt und ein PowerShell-Script Abfrage_Kerndaten.ps1 erstellt, gepackt sowie das Archiv Abfrage_Kerndaten.zip hier angefügt. Mit folgendem Befehl werden die wichtigsten Kerndaten dann wirklich in PowerShell angezeigt:
Code:
powershell -ExecutionPolicy Bypass -File "E:\Abfrage_Kerndaten\Abfrage_Kerndaten.ps1"

Ergebnis:

Kerndaten.png (Zum Vergrößern anklicken)

PS: Pfad zum PowerShell-Script Abfrage_Kerndaten.ps1 muss natürlich angepasst werden.
 

Anhänge

  • Abfrage_Kerndaten.zip
    861 Bytes · Aufrufe: 51
Es geht noch eleganter ;););)
$Mein_Betriebssystem = (Get-WmiObject -class Win32_OperatingSystem).Caption
$Version = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion').DisplayVersion
$Architektur = (Get-CimInstance Win32_operatingsystem).OSArchitecture
$Buildnummer = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion').CurrentBuild
$Erweiterung = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion').UBR
$Computername = (Get-CimInstance Win32_ComputerSystem).Name
$Meine_Domaene = (Get-CimInstance Win32_ComputerSystem).Domain
$Benutzername = (Get-CimInstance Win32_ComputerSystem).PrimaryOwnerName
$User_ID = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.value
Write-Host ('
Die wichtigsten Kerndaten dieses Systems werden hier mit Powershell angezeigt.')
Write-Host
Write-Host Auf Ihrem Coumputer ist $Mein_Betriebssystem, Version $Version als $Architektur'-'Betriebssystem installiert.
Write-Host
Write-Host Die momentane Buildnummer lautet $Buildnummer'.'$Erweiterung'.'
Write-Host
Write-Host Der Name dieses Computers lautet $Computername'.'
Write-Host
Write-Host Der Name der Arbeitsgruppe lautet $Meine_Domaene'.'
Write-Host
Write-Host Die User-ID des momentan angemeldeten Benutzers $Benutzername lautet $User_ID'.'
Write-Host
Write-Host Zum Beenden drücken Sie eine beliebige Taste . . .

[void]($Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown'))

exit

Nur die Auflösung ist nicht mehr drin...
 

Anhänge

  • Abfrage_Kerndaten_mein.zip
    1,7 KB · Aufrufe: 51
Zuletzt bearbeitet:
Da habe ich noch eine kleine, wenn auch unausgereifte Spielerei
write-host Die Bildschirmauflösung beträgt
write-host " "
Get-WmiObject -Class Win32_videocontroller | Select-Object currenthorizontalresolution | format-table -hidetableheaders
write-host Bildpunkte horizontal
write-host " "
Write-host und
Get-WmiObject -Class Win32_videocontroller | Select-Object currentverticalresolution | format-table -hidetableheaders
write-host Bildpunkte vertikal
write-host " "
pause
Ansi-Format nicht vergessen!
Und Zeilenumbrüche beachten... es gehört in eine Zeile -hidetableheaders
 
gwmi -Class Win32_videocontroller | select currenthorizontalresolution |fl

Das in eine Variable $hori setzen aber eben halt nur den Wert das bekomme ich noch nicht hin

gwmi -Class Win32_videocontroller | select currentverticalresolution |fl

Das in eine Variable $verti setzen aber eben halt nur den Wert das bekomme ich noch nicht hin

Diese Variablen dann mit nem schönen Satz in ein Powershellscript

write- host "Die momentane Bildschirmauflösung beträgt $hori Bildpunkte horizontal und $verti Bildpunkte vertikal" -nownewline
 
Status
Dieses Thema wurde gelöst! Lösung ansehen…
Für weitere Antworten geschlossen.
Anzeige
Oben