Alternative Datenströme sind eine erweiterte Funktion des NTFS-Dateisystems, die es erlaubt, beliebige Meta-Informationen über Dateien zusammen mit der Datei abzulegen. Windows verwendet z.B. einen Alternativen Datenstrom, um das MotW (Mark of the Web) zu speichern. Das MofW wird beim Download einer Datei automatisch gesetzt, damit Windows Sicherhe...
EMClient ist ein Email-Client, der alle wesentlichen Funktionen von MS Outlook abdeckt, dabei aber deutlich flexibler konfigurierbar ist und ein zu MS Outlook sehr ähnliches Design hat, was die Migration von MS Outlook einfach macht. Im Gegensatz zu Outlook fügt EMClient geteilte Mailboxen allerdings nicht automatisch der Postfachansicht hinzu. Sta...
Um aus einer Liste von Datumswerten (z.B. aus einer Logdatei) nur einen Wert pro Zeiteinheit (also z.B. pro Sekunde) auszugeben, erstellt man sich zuerst einen Wert, der die Sprungweite speichert. Da Powershell Zeitwerte in 10.000.000stel Sekunden - den sogenannten Ticks - speichert, muss die Sprungweite mit den Ticks pro Zeiteinheit multipli...
Reguläre Ausdrücke sind in allen Programmier-Sprachen ein mächtiges Werkzeug, um Texte zu analysieren und aufzubrechen. In Powershell steht einem hierfür unter anderem der Vergleichsoperator -match zur Verfügung. Reguläre Ausdrücke reichen dabei von sehr einfach bis sehr kompliziert. Das folgende Beispiel fällt z.B. in die erste Kategorie: 'C:...
Wenn Sie auf einem Dateiserver Ordner umziehen müssen, kann das Anpassen der Freigaben auf untergeordneten Ordnern sehr aufwändig werden, z.B. wenn es sich um eine große Menge von Home-Shares handelt. Einfacher als über die GUI geht es, wenn Sie die Registry-Schlüssel unter HKEY_LocalMachine\SYSTEM\CurrentControlSet\Services\LanmanServer\Shares\ anpassen. Alternativ können einfach die folgende Powershell-Funktion verwenden, die einen gegebenen Pfad in dem Registry-Schlüssel durch einen neuen ersetzt. Da es sich um eine reine Musterersetzung handelt, können Sie beliebige Teilpfade ersetzen lassen.
function Replace-SharePath
{
<#
.SYNOPSIS
Replace the Filesystem-Path of a Share
.Description
Replace-Sharepath can change the Filesystem-Path of shares. This can be helpful if you need to move
Files to a new Drive or have to move files to a subfolder and you have multiple Shares to touch. The
Script will change the given String into the new string, so all shares under the given Path will be
affected.
.EXAMPLE
To move Files from C:\Shares to D:\NewSharesFolder:
Replace-SharePath -Path c:\Shares -NewPath D:\NewSharesFolder
#>
param(
[ValidateScript({ if ( ! ( Test-Path -path $_ -PathType Container )) {Throw "Bitte den Quellpfad prüfen!"}; $true })]
[Parameter(mandatory=$true)]
# The Path to Change.
$Path,
[ValidateScript({ if ( ! ( Test-Path -path $_ -PathType Container )) {Throw "Bitte den Quellpfad prüfen!"}; $true })]
[Parameter(mandatory=$true)]
# The New Path
$Newpath
)
$path = $Path.Replace('\','\\')
$Newpath = $Newpath.Replace('\','\')
$ShareList = Get-Item HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Shares\
ForEach ( $Share in $ShareList.Property )
{
Get-ItemProperty -Path $ShareList.pspath -Name $share
$newValue = ( Get-ItemProperty -Path $ShareList.pspath -Name $share ).$Share -replace "(^Path=)($path)","Path=$newpath"
Set-ItemProperty -Path $ShareList.pspath -Name $Share -Value $Newvalue -PassThru
}
}
Virtuelle Maschinen mit Hyper-V anzulegen ist in Powershell mit den beiden Cmdlets New-VM und Set-VM relativ einfach, da die Cmdlets alle wesentlichen Funktionen einer virtuellen Maschine mit den Standard-Parametern abbilden. Das Aktivieren des virtuellen TPMs gestaltet sich aber überraschend schwierig. Während man im Hyper-V Manager nur ein H...
Python kann mit dem json-Modul Strings im JSON-Format direkt in einen Dictionary konvertieren. Zum Import aus einer JSON-Datei muss man die Datei zuerst mit open einlesen. import jsonwith open('c:\user.json') as user: message = json.load(user) Python erwartet hier, wie im JSON-Standard definiert, eine in UTF8 codierte Datei ohne BOM...
Hat man das Windows Subsystem für Linux installiert und arbeitet in der Bash mit der Kommandozeilenergänzung per Tabulator, wird man ein ziemlich nerviges Sound-Feedback in Form eines Pings kaum überhören können. Um den Ping abzuschalten, muß man die Datei /etc/inputrc editieren und die Konfigurations-Schlüssel bell-style auf none setzen - nor...
Wenn die Google Search Console auf Ihrer Joomla-Website ungültige AMP-Seiten erkennt, könnte das an der Mail-Cloaking Funktion von Joomla liegen, die seit Version 4.10 standardmäßig aktiviert ist. Mail-Cloaking verschleiert E-Mail-Adressen automatisch mit JavaScript-Code, indem die Email-Adresse verschlüsselt in ein Tag <joomla-hidden-mail> e...
Send-Mailmessage ist ein sehr nützliches Cmdlet, um Emails direkt aus Powershell an einen Mailserver zu senden. Er steht seit Powershell 2.0 zur Verfügung und vermeidet so, dass man sich direkt mit dem [System.net.mail]-Typ herumschlagen muß. Allerdings zeigt das Cmdlet ein sehr merkwürdiges Fehlerverhalten.
Wenn man versucht, Verbindungsfehler abzufangen, ist ein erster vernünftiger Ansatz, einfach auf den Parameter -Errorvariable zurückzugreifen:
Send-Mailmessage -SmtpServer mail.meineFirma.de -Subject 'Warnung' -Body 'Hier kommt die Maus' -From 'Elefant@netz-weise.xyz' -to 'Maulwurf@netz-weise.xyz' -ErrorVariable Fehlermeldung
If ( $Fehlermeldung ) { $Fehlermeldung.Exception.Message }
Tritt ein Fehler auf, wird dieser direkt in der Variablen $Fehlermeldung gespeichert. Achtung, bei der Angabe der Fehlervariablen wird kein $-Zeichen angegeben!
Seit Mai 2022 hat Exchange eine neue Funktion erhalten, die sich wunderbar verwenden lässt, um eingehende Newsletter-mails und ähnliches automatisch zu sortieren. Diese Funktion nennt sich Plus-Adressierung, weil man in die eigene Email-Adresse einfach ein + gefolgt von einem selbstgewählten Text erweitern kann, die dann ...
Mit dem SQL-Server Agent und der Datenbankrolle ""SQLAgentUserRole"" in der msdb-Datenbank kann man einem SQL-Login Zugriff auf einen Job geben. Voraussetzung ist, dass der Login dem JOB auch als Owner zugewiesen wird. Soll der User allerdings auch die Zeitpläne für geplante Aufträge verwalten, stellt man fest, dass dies nicht unbedingt klappt. Ursache dafür ist die schlecht Dokumentierte Tatsache, dass der Login auch Besitzer der Zeitpläne sein muß. Hat er diese nicht angelegt, kann er dementsprechend keine Änderungen durchführen. Stattdessen bekommt er eine Meldung "The specified schedule @schedule_id() does not exist". Den Besitzer des Zeitplans kann man nur über die Tabelle msdb.dbo.sysschedules in der Spalte owner_sid einsehen. Das folgende Script zeigt alle Job an, bei denen Besitzer für Zeitplan und Job nicht identisch sind:
SELECT (SELECT name FROM sys.server_principals WHERE [SID] = ss.owner_sid) AS ScheduleOwner,
(SELECT name FROM sys.server_principals WHERE [SID] = sj.owner_sid) AS JobOwner,
ss.name AS ScheduleName,
ss.owner_sid AS ScheduleOwnerSid,
sj.name AS JobName,
sj.owner_sid AS JobOwnerSID
FROM msdb.dbo.sysschedules AS ss
INNER JOIN msdb.dbo.sysjobschedules AS sjs
ON sjs.schedule_id = ss.schedule_id
INNER JOIN msdb.dbo.sysjobs AS sj
ON sjs.job_id = sj.job_id
WHERE ss.owner_sid <> sj.owner_sid
Und mit folgendem Script beheben Sie das Problem, indem Sie den Besitzer aller zeitpläne auf den gleichen Besitzer setzen wie den zugehörigen Job. Um nicht alle Jobs ungesehen zu überschreiben, geben Sie in der 1. Zeile einen Login-Namen ein:
DECLARE @JobOwner NVARCHAR(255) = 'Benutzer'
DECLARE @JobOwnerSid VARBINARY(85)
SELECT @JobOwnerSid = [sid] FROM master.sys.server_principals WHERE name = @JobOwner
UPDATE SS
SET ss.owner_sid = sj.owner_sid
FROM msdb.dbo.sysschedules AS ss
INNER JOIN msdb.dbo.sysjobschedules AS sjs
ON sjs.schedule_id = ss.schedule_id
INNER JOIN msdb.dbo.sysjobs AS sj
ON sjs.job_id = sj.job_id
WHERE (ss.owner_sid <> sj.owner_sid)
AND (sj.owner_sid = @JobOwnerSid)
Seit einiger Zeit habe ich auf mehreren Windows 11-Rechnern ein ziemlich merkwürdiges Problem - einige Icons in der Taskleiste werden mit einem Standard-Icon statt mit dem zugehörigen Programm-Icon angezeigt. Das Problem scheint ein Bug in Windows 11 zu sein, und die Ursache ist ein korrupter Icon Cache. Grundsätzlich kann man das Problem relativ e...
Um in einem Skript zwischen HDDs und SSDs zu unterscheiden, kann man seit Windows 8 auf das Cmdlet Get-PhysicalDisk zurückgreifen. Es liefert ein MSFT_PhysicalDisk-Objekt zurück, das unter https://docs.microsoft.com/en-us/previous-versions/windows/desktop/stormgmt/msft-physicaldisk beschrieben ist. Die Eigenschaft MediaType enthält den Datenträgertyp (HDD,SSD).
Das Cmdlet Get-Physicaldisk ist als CDXML-basiertes Cmdlet implementiert und fragt im Prinzip einfach nur die Klasse MSFT_PhyscialDisk ab. Das kann man auch direkt erledigen.
Get-CimInstance MSFT_Physicaldisk -Namespace root\Microsoft\Windows\Storage
Wichtig - Die Klasse MSFT_PhysicalDisk befindet sich nicht im Standard-Namespace CimV2, daher ist es wichtig, den Namespace mit anzugeben.
Warum sollte man die Klasse direkt abfragen? Z.B. wenn einem die Storage-Cmdlets nicht zur Verfügung stehen, oder wenn man nicht sicher weiß, ob die Cmdlets verfügbar sind. Außerdem kann man mit Get-CimClass die Abfrage auch direkt einschränken, was schneller geht als über Get-PhysicalDisk und Where-Object zu filtern:
Wussten Sie, dass die Standardberechtigungen des AD jedem Benutzer den Zugriff auf alle Benutzer-, Gruppen- und Computerobjekte erlauben? Natürlich ist dieser Zugriff eingeschränkt - sensible Informationen sind weder einseh- noch änderbar. Nichtsdestotrotz kann diese Funktion sehr hilfreich sein, da es einem Benutzer so z.B. ermöglicht wird, nach e...
Seit Windows Server 2019 und Windows 10 werden Fensterrahmen nicht mehr angezeigt. Diese Designentscheidung finde ich schon aus ästhetischen Gründen fragwürdig, aus ergonomischer Sicht ist es jedenfalls völlig daneben, da man, wenn man mehrere Fenster übereinander legt, die Fenster kaum noch zu unterscheiden sind. Glücklicherweise gibt es...
Der gigantische Wurf bleibt aus, was nicht verwunderlich ist, gibt es doch seit der Cloud antizyklisch und häufiger kleinere und größere Updates.Insgesamt verfolgt Adobe den Plan serverbasierte Dienste stärker in den Focus zu rücken:Weg vom Desktop, rein in die Cloud.Klar, das das nicht einfach ist, technisch, wie auch in dem Köpfen der Benutzer, s...
Dieser Blogpost ist eine kurze Zusammenfassung von Powershell Runspaces am Beispiel eines Massenping. Ich fasse das Thema hier zusammen, weil Runspaces immer sehr mächtig und komplziert wirken, obwohl sie tatsächlich mit wenigen Zeilen Text beschrieben werden können. Das Problem: Ein Skript soll anhand einer bekannten Adresse (des Routers) herausfi...
Manchmal steht man vor der Aufgabe, das einzelne mails aus einem Benutzerpostfach gelöscht werden sollen, z.B. weil Sie Schadcode enthalten, oder auch, weil das Postfach geleert werden soll. Mit Hilfe der Exchange-eigenen Cmdlet Search-Mailbox geht das sehr einfach.
Starten Sie die Exchange Management-Shell. Eine Anleitung der Installation der Shell finden Sie im Artikel "Exchange Cmdlet in Powershell nutzen". Achten Sie darauf, dass Sie das Cmdlet "Search-Mailbox" nicht sehen, solange Sie nicht Mitglieder der Rolle "Mailbox Import Export" sind - das gilt sogar dann, wenn Sie als Organisationsadministrator angemeldet sind. Alternativ können Sie das Problem auch umgehen, indem Sie die Exchange-Snapins direkt importieren.
Anschliessend rufen Sie das Cmdlet Search-Mailbox auf. Der Parameter Identity gibt dabei an, welche Mailbox(en) Sie suchen. Alternativ können Sie die Mailboxen auch per Pipeline an Search-Mailbox übergeben. Mit Hilfe des Parameters -Searchquery geben Sie an, welche Nachrichten gesucht werden. Das Cmdlet verwendet für die Definition der Suchabfragen die KQL (Keyword Query Language). Ein einfaches Beispiel für eine Suche nach dem Begriff "Verrat" in allen mails aller mailboxen sieht so aus:
Get-Mailbox | Search-Mailbox -SearchQuery 'Verrat' -TargetMailbox 'Administrator' -TargetFolder 'NSA'
Heute stand ich vor der Aufgabe, eine MAC-Adresse einzulesen. Das Einlesen der MAC-Adresse gestaltet sich dabei einfach. Unter Windows am einfachsten geht das über Get-Netadapter:
PS > Get-NetAdapter
Name InterfaceDescription ifIndex Status MacAddress LinkSpeed
---- -------------------- ------- ------ ---------- ---------
Internal Microsoft Hyper-V Network Adapter 10 Up 00-15-5D-64-98-00 10 Gbps
Unter Windows PE steht das Cmdlet leider nicht zur Verfügung, da es zu den CDXML-Datei basierten Cmdlets gehört. Glücklicherweise kann man sich behelfen, indem man einfach auf Get-WMIObject zurückgreift:
PS > Get-WmiObject -Class win32_networkadapter