Open with notepad

Weil ichs dauernd vergesse:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\Open with Notepad]

[HKEY_CLASSES_ROOT\*\shell\Open with Notepad\Command]
@="notepad \"%1\""

 

Mehr Cores für Android Emulator

Android Device Manager in Visual Studio 2017 legt Android Emulator VMs IMMER mit 2 Cores an – wo doch jeder weiß dass ein Android unter 4 Cores in Wahrheit unbenutzbar ist eine sehr fragwürdige Entscheidung. Die Emulatoren sind völlig überraschend schweinelangsam – und es gibt keinen Parameter wo man das easy raufstellen könnte.

Lösung: Emulator manuell starten mit Parameter -cores XX oder im Device Manager einen Custom Parameter namens hw.cpu.ncore hinzufügen und als Wert die gewünschten Cores angeben:

SMA Sunny Home Manager + Sunny Island an A1 Router

….schlechte Idee. Offenbar blockt der A1 Router (und vermutlich viele viele andere auch) Teile der Kommunikation zwischen Manager und Island (oder kann was nicht was dafür notwendig wäre, die Zauberwörter “IGMP Snooping” tauchen hier auf, mag aber auch was ganz andreas sein) – aber nicht 100% zuverlässig sodass es manchmal funktioniert und manchmal eben nicht.

Nach mehreren Stunden des mehr oder weniger erfolgreichen Probierens hat dann alles funktioniert – Reset probiert (um zu sehen was z.B. bei Stromausfall passiert) und (natürlich) war wieder alles weg und konnte nicht restauriert werden.

Aus reiner Verzweiflung dann einen dummen Switch für Manager und Island genommen, gegen Router uplinked und alles funktioniert auf Anhieb….irgendwann am Weg auch Island von DHCP auf statische Adresse umgestellt, keine Ahnung ob das mitwirkt, schaden tuts bei der Turboblackbox Manager sicher nicht. 😀

Hier konkret:
* Sunny Home Manager 2.0
* Sunny Island 6.0H-12

Zertifikatswechsel ADFS (3.0 / Service-Communication)

….weil die Konsole offenbar nicht immer das macht was sie soll:

  • neues Zertifikat importieren (nanonaned)
  • NT SERVICE\adfssrv auf private Key berechtigen (read), alternativ Service Account
  • Set-AdfsSslCertificate -Thumbprint xxxx
  • Kontrolle mit netsh http show sslcert
  • ADFS Service restarten

Setzen via Console hat die Config aber nicht die Bindings geändert, auch nach Reboot nicht, Set-AdfsCertificate -CertificateType Service-Communications detto.

Zertifikatswechsel Web Application Proxy (ADFS)

….wenn Set-WebApplicationProxySslCertificate nicht will (warum auch immer):

  • neues Zertifikat importieren (Überraschung!)
  • HKLM\Software\Microsoft\ADFS\ProxyConfigurationStatus von 2 (=konfiguriert) auf 1 (=nicht konfiguriert) setzen
  • mit Wizard neue Verbindung zu herstellen (Name=öffentlicher Name vom ADFS, Zertifikat ist klar, User wird nur für Herstellung der Verbindung benötigt)

    oder

  • Install-WebApplicationProxy -FederationServiceTrustCredential (get-credential) -FederationServiceName meinadfs.meinedomain.whatever -CertificateThumbprint xxx

Zertifikatswechsel Office WebApps Server wenns schon zu spät ist

….sprich es abgelaufen ist und das Service nicht mehr startet. Powershell und Set-OfficeWebAppsFarm funktioniert dann sinnigerweise ja nicht mehr.

Lösung:

  • neues Zertifikat importieren (völlig überraschend)
  • Friendly Name vergeben
  • Setting “CertificateName” in C:\ProgramData\Microsoft\OfficeWebApps\Data\FarmState\settings.xml auf den neuen Friendly Name ändern
  • Service starten
  • freuen

ASP.NET Core WebAPI Cheat Sheet

Visual Studio: ASP.NET Core project (empty oder WebAPI)

empty:

Startup.cs:

ConfigureServices: services.AddMvc()

Configure: app.UseMvc()

“Controllers” Ordner erzeugen

New item: API Controller Class, Base class auf ControllerBase ändern (weniger Intellisync)

 

ROUTING

Class Routing: [Route("bli/bla")] als Controllerklassenattribut wird allen Actions vorgestellt. [Controller] in der Route wird durch Klassenname (muss mit “Controller” enden) ohne “Controller” ersetzt.

Atrribute Routing: [HttpGet/Post/Put/Delete("route")] vor Methode.
{bli} = Parameter “bli” in Methode wird aus Route geholt
{bla:int} = Parameter “bla” in Methode wird als int aus Route geholt (nur dann wenns auch ein int ist)
{bla:string:minlength(7)} = Parameter “blu” in Methode wird als string aus Route geholt, String muss mind. 7 Zeichen lang sein
{foo?} = optionaler Parameter
{bar=4711} = Defaultwert (sonst 0 bei int und “” bei string)
{wtf:regex(^abc…xyz$)} = Route greift nur wenn regular Expression matched

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing

 

MODEL BINDING

Parameter in Action vorangestellt [FromRoute] (default), [FromBody], [FromQuery], [FromForm], [FromHeader] zwingt ASP.NET Core gleichnamigen Parameter aus dieser Quelle zu beziehen.

Immer ModelState.IsValid prüfen um sicherzustellen dass alle Bindings und Contraints erfolgreich ausgewertet wurden.

DataAnnoations bei Properties von komplexen Typen (z.B. [MinLength(7)] public string Bli { get; set; } in einer Klasse) werden für ModelState ausgewertet (public und get/set sind notwendig!).

https://docs.microsoft.com/en-us/aspnet/core/mvc/models/validation

 

ACTION RESULTS

Actions liefern IActionResult anstatt Basistypen, ermöglicht clientseitig besseres Ergebnismanagement (v.a. im Fehlerfall – Exception würde sonst immer 500 liefern anstatt sinnvoller Informationen).

return NotFound()  = 404
return BadRequest() oder BadRequest(ModelState) = 400, alternativ mit Zusatzinformation (Validation-Fehler z.B.)
return Ok() oder Ok(“whatever”) oder Ok(new { bli=”bla”, blu=”blu”}) = 200 mit Wert im Body (Object wird zu JSON)

https://docs.microsoft.com/en-us/aspnet/core/web-api/action-return-types

 

SECURITY – TRANSPORT

Für MVC kann man verschiedenste Filter einfügen, zwei der wichtigsten (Antiforgery Token (eigentlich nicht Transport aber he…) und Require HTTPS gehen so) – in ConfigureServices():

services.AddMvc(options =>
{
   options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
   options.Filters.Add(new RequireHttpsAttribute());
});

In der Configure Methode der Startup-Klasse (Startup.cs) gibts vielfache Möglichkeiten die Transportsicherheit zu erhöhen:

app.UseHttpsRedirection() = offensichtlich
app.UseHsts() = offensichtlich

Das ist aber eher dürftig, viele zusätzliche Securityheader bekommt man über diverse Nugets:

Nwebsec.AspnetCore.Middleware (https://docs.nwebsec.com/en/latest/nwebsec/NWebsec.AspNetCore.Middleware.html)
app.UseHsts(options => options.MaxAge(days: 365).IncludeSubdomains()) = offensichtlich aber mit Parameter
app.UseXXssProtections(options => options.EnableWithBlockMode()) = Cross Side Scripting Header, mit Parameter
app.UseXcontentTypeOptions() = X-Content-Type-Options Header
app.UseXfo(options => options.Deny()) = X-Frame-Options Header
app.UseReferrerPolicy(opts => opts.NoReferrer()) = Referrer Policy
app.UseCsp(…crazy zeug…) = Content Security Policy, siehe Doku, vielfältigste Möglichkeiten sich selbst die Knie wegzuschießen

NetEscapades.AspnetCore.SecurityHeaders (https://andrewlock.net/adding-default-security-headers-in-asp-net-core/)
app.UseSecurityHeaders(new HeaderPolicyCollection().AddDefaultSecurityHeaders()) = für die die etwas schreibfauler sind 😀

 

SECURITY – AUTHENTICATION UND AUTHORIZATION

Am Beispiel ADFS – in ConfigureServices() Authentication enablen:

services.AddAuthentication(sharedOptions =>
  {
     sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
     sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
     sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
  }).AddWsFederation(options =>
     {
        options.MetadataAddress = "https://myadfs.mydomain.com/FederationMetadata/2007-06/FederationMetadata.xml";
        options.Wtrealm = "https://myrelyingpartytrust/";
     }).AddCookie(options =>
        {
           options.AccessDeniedPath = new PathString("/api/mycontroller/myaccessdeniedaction");
        });

Wobei der Relying Party Trust im ADFS natürlich entsprechend eingetragen werden muss (WS-Federation) und die entsprechenden Claims issued werden müssen. Wtrealm ist der Relying Party Trust Identifier.

Authorization kann schon am ADFS passieren (Issuance Authorization Rules) oder auf WebAPI Seite mit dem [Authorize] oder [AllowAnonymous]  Attribut gesetzt auf Klasse (Controller) oder Methode (Action). Gemeinsame Regeln kann man in Policies in ConfigureService() mit Name erzeugen

services.AddAuthorization(options =>
    {
       options.AddPolicy("MyPolicy", policy => policy.RequireClaim("http://schemas.xmlsoap.org/claims/Group", "MyAdminGroup"));
    });

und dann im Klassen/Methodenattribute verwenden ([Authorize(Policy="MyPolicy")])

SCCM Client Update failed mit 0x8004402F beim MOFCOMP

Szenario: Update SCCM Server auf 1806, Client-Auto-Update enabled, einige Clients weigern sich standhaft auf die neue Version zu aktualisieren. Im CLIENT.MSI.LOG gibts zig Einträge mit Fehler 8004402F beim MOFCOMP, Beispiel:

[19:30:57] Failed to compile 'C:\Windows\CCM\ccmclasses.mof' (Phase: 2, Object: 0, Lines: 0 - 0, Error: 8004402F)

Grund (in meinem Fall zu mindestens): In %TEMP% vom System Account (C:\WINDOWS\TEMP bei mir) waren über 65.000 temporäre Dateien mit dem Muster TMPabcd.TMP, offenbar sind dem System die möglichen Kombinationen für abcd ausgegangen und MOFCOMP braucht aber eine (oder mehrere) temporäre Dateien. TMP*.TMP gelöscht und das SCCM Client Setup flutscht wieder.

DPM Agent in untrusted domain

Nachdem ich jetzt schon mehrfach eingefahren bin, SetDpmServer.exe -dpmServerName xxxx -isNonDomainServer -userName yyyy macht folgendes (abseits von dem was es auf dem Bildschirm ausgibt):

* der lokale User (Agent UND DPM Server!!!) wird mit den notwendigen Gruppen neu versorgt
* “Password does not expire” wird vom lokalen Account entfernt
* “User must change password at next logon” wird NICHT entfernt

Setzt man also nach dem Kommando nicht die entsprechenden Flags auf den lokalen Usern neu und läuft das Kennwort ab bekommt man die coolsten Fehlermeldungen ala “A DPM agent failed to communicate with the DPM service” und ähnliches aber KEINERLEI Hinweise auf das Problem mit dem Konto….