Als Erweiterung zu https://roman.gallauner.at/default-papiergroesse-papersize-eines-druckers-mit-powershell-aendern/ hier eine Funktion mit der man benutzerdefinierte Etikettengrößen pro Drucker setzen kann (wenn PaperSize im vordefinierten Layout mal “fluktuiert” – soll ja angeblich passieren…):

param([switch]$Debug)

# https://www.codeproject.com/Articles/6899/Changing-printer-settings-using-C

$c=@'
using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
using Microsoft.Win32;

   public class PrinterSettings
   {
      [DllImport("kernel32.dll", EntryPoint = "GetLastError", SetLastError = false, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
      private static extern Int32 GetLastError();

      [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
      private static extern bool ClosePrinter(IntPtr hPrinter);

      [DllImport("winspool.Drv", EntryPoint="DocumentPropertiesA", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
      private static extern int DocumentProperties(IntPtr hwnd, IntPtr hPrinter, [MarshalAs(UnmanagedType.LPStr)] string pDeviceName, IntPtr pDevModeOutput, ref IntPtr pDevModeInput, int fMode);

      [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
      private static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr PrinterDefaults);

      [DllImport("winspool.drv", CharSet = CharSet.Ansi, SetLastError = true)]
      private static extern bool SetPrinter(IntPtr hPrinter, int Level, IntPtr pPrinter, int Command);

      [StructLayout(LayoutKind.Sequential)]
      public struct PRINTER_INFO_9
      {
         public IntPtr pDevMode;
      }

      private const short CCDEVICENAME = 32;
      private const short CCFORMNAME = 32;
      [StructLayout(LayoutKind.Sequential)]
      public struct DEVMODE
      {
         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCDEVICENAME)]
         public string dmDeviceName;
         public short dmSpecVersion;
         public short dmDriverVersion;
         public short dmSize;
         public short dmDriverExtra;
         public int dmFields;
         public short dmOrientation;
         public short dmPaperSize;
         public short dmPaperLength;
         public short dmPaperWidth;
         public short dmScale;
         public short dmCopies;
         public short dmDefaultSource;
         public short dmPrintQuality;
         public short dmColor;
         public short dmDuplex;
         public short dmYResolution;
         public short dmTTOption;
         public short dmCollate;
         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCFORMNAME)]
         public string dmFormName;
         public short dmUnusedPadding;
         public short dmBitsPerPel;
         public int dmPelsWidth;
         public int dmPelsHeight;
         public int dmDisplayFlags;
         public int dmDisplayFrequency;
      }
      private const int PRINTER_ACCESS_USE = 0x8;
      private const int DM_OUT_BUFFER = 0x2;
      private const int DM_MODIFY = 0x8;
      private const int DM_PAPERSIZE = 0x2;
      private const int DM_PAPERLENGTH = 0x4;
      private const int DM_PAPERWIDTH = 0x8;

      public static bool ChangePaperSize(string sPrinterName, short nSize, short nWidth, short nHeight, out string sDebug)
      {
         DEVMODE oDM;
         IntPtr pNativeDM = IntPtr.Zero;
         int nBytesNeeded = 0;
         IntPtr hPrinter = new System.IntPtr();
         PRINTER_INFO_9 oPrinterInfo;
         IntPtr pNativePrinterInfo = IntPtr.Zero;
         IntPtr pDummy=IntPtr.Zero;
         bool bChanged=false;

         sDebug="";

         //Console.WriteLine("Open printer");
         if (!OpenPrinter(sPrinterName, out hPrinter, IntPtr.Zero))
         {
            Console.WriteLine("OpenPrinter() failed with error "+Marshal.GetLastWin32Error()+", aborting.");
            sDebug += "OpenPrinter() failed with error "+Marshal.GetLastWin32Error()+", aborting.\n";
            return false;
         }

         //Console.WriteLine("Getting bytes needed for DEVMODE via DocumentProperties");
         nBytesNeeded=DocumentProperties(IntPtr.Zero,hPrinter,sPrinterName,IntPtr.Zero,ref pDummy,0);
         //Console.WriteLine("Bytes needed: "+nBytesNeeded+", allocating.");
         pNativeDM=Marshal.AllocHGlobal(nBytesNeeded);
         //Console.WriteLine("Fetching DEVMODE via DocumentProperties");
         DocumentProperties(IntPtr.Zero,hPrinter,sPrinterName,pNativeDM,ref pDummy,DM_OUT_BUFFER);
         oDM = (DEVMODE)Marshal.PtrToStructure(pNativeDM, typeof(DEVMODE));
         //Console.WriteLine("Free native DM");
         Marshal.FreeHGlobal(pNativeDM);

         //Console.WriteLine("Old size: "+oDM.dmPaperSize);
         if (oDM.dmPaperSize != nSize)
         {
            Console.WriteLine("dmPaperSize="+oDM.dmPaperSize+" => "+nSize);
            sDebug += "dmPaperSize="+oDM.dmPaperSize+" => "+nSize + "\n";
            oDM.dmPaperSize = nSize;
            oDM.dmFields |= DM_PAPERSIZE;
            bChanged=true;
         }

         if (nWidth != 0 && oDM.dmPaperWidth != nWidth) 
         { 
            Console.WriteLine("dmPaperWidth="+oDM.dmPaperWidth+" => " +nWidth);
            sDebug += "dmPaperWidth="+oDM.dmPaperWidth+" => " +nWidth + "\n";
            oDM.dmPaperWidth=nWidth; 
            oDM.dmFields |= DM_PAPERWIDTH; 
            bChanged=true;
         }
         if (nHeight != 0 && oDM.dmPaperLength != nHeight) 
         { 
            Console.WriteLine("dmPaperLength="+oDM.dmPaperLength+" => " +nHeight);
            sDebug += "dmPaperLength="+oDM.dmPaperLength+" => " +nHeight + "\n";
            oDM.dmPaperLength=nHeight; 
            oDM.dmFields |= DM_PAPERLENGTH; 
            bChanged=true;
         }

         if (bChanged)
         {
            //Console.WriteLine("Allocating memory for new native DEVMODE");
            pNativeDM = Marshal.AllocHGlobal(Marshal.SizeOf(oDM));
            //Console.WriteLine("Copy managed DEVMODE to native memory");
            Marshal.StructureToPtr(oDM, pNativeDM, true);

            //Console.WriteLine("Modifying DEVMODE with DocumentProperties");
            DocumentProperties(IntPtr.Zero,hPrinter,sPrinterName,pNativeDM,ref pDummy,DM_MODIFY);

            oPrinterInfo.pDevMode = pNativeDM;
            //Console.WriteLine("Copy managed PRINTER_INFO_9 to native memory");
            pNativePrinterInfo = Marshal.AllocHGlobal(Marshal.SizeOf(oPrinterInfo));
            Marshal.StructureToPtr(oPrinterInfo, pNativePrinterInfo, true);
            //Console.WriteLine("Writing new PRINTER_INFO_9 to printer");
            if (!SetPrinter(hPrinter, 9, pNativePrinterInfo, 0))
            {
               Console.WriteLine("SetPrinter() failed with error "+Marshal.GetLastWin32Error()+", aborting.");
               sDebug += "SetPrinter() failed with error "+Marshal.GetLastWin32Error()+", aborting.\n";
               Cleanup(pNativeDM, pNativePrinterInfo, hPrinter);
               return false;
            }
            Cleanup(pNativeDM, pNativePrinterInfo, hPrinter);
         }
         else
         {
            Console.WriteLine("Nothing to do, exiting.");
            sDebug += "Nothing to do, exiting.\n";
         }
         return true;
      }

      public static void Cleanup(IntPtr pNativeDM,IntPtr pNativePrinterInfo,IntPtr hPrinter)
      {
         try
         {
            //Console.WriteLine("Memory and handle cleanup");
            if (hPrinter != IntPtr.Zero) ClosePrinter(hPrinter);
            if (pNativeDM != IntPtr.Zero) Marshal.FreeHGlobal(pNativeDM);
            if (pNativePrinterInfo != IntPtr.Zero) Marshal.FreeHGlobal(pNativePrinterInfo);
         }
         catch (Exception)
         {
         }
      }
   }
'@

if ($Debug)
{
   Start-Transcript "$($env:Temp)\PaperSize.log"
}

Add-Type -TypeDefinition $c -ReferencedAssemblies System.Runtime.InteropServices,System.ComponentModel 
Add-Type -AssemblyName System.Drawing

$printers="\\printserver\printer1~495~360#\\printserver\printer2~USER~495~360"

foreach ($printerinfo in $printers.Split('#'))
{
   Write-Host "====================================================="
   $printer=$printerinfo.Split('~')[0]
   $paper=$printerinfo.Split('~')[1]
   $width=$printerinfo.Split('~')[2]
   $height=$printerinfo.Split('~')[3]

   $ps=New-Object System.Drawing.Printing.PrinterSettings
   $ps.PrinterName=$printer
   $size=$ps.PaperSizes|? PaperName -eq $paper

   if ($null -ne $size) 
   {
       Write-Host "$($printer): size (raw): $($size.RawKind)"

       $messages=""
       $success=[PrinterSettings]::ChangePaperSize($printer,$size.RawKind,$width,$height,[ref]$messages)
       if ($Debug) { $messages }
       if ($success)
       {
          Write-Host "   ==> SUCCESS"
       }
       else
       {
          Write-Host "   ==> ERROR"
       }
   }
   else
   {
      Write-Host "$($printer): PaperSize $($paper) not found."
   }
}

if ($Debug)
{
   Stop-Transcript
}