Automatizimi i trajtimit të klasës kompjuterike me Powershell

Automatizimi i trajtimit të klasës kompjuterike me Powershell

Kam disa vite merrem me mbështetje për 10 stacione pune në universitet, të drejtuara nga sistemi operativ Microsoft Windows 8.1. Kryesisht, mbështetja konsiston në instalimin e softuerëve të nevojshëm për procesin mësimor dhe sigurinë e funksionimit të përgjithshëm.

Në çdo stacion ka 2 përdorues: Administrator dhe Student. Administratori ka akses të plotë, ndërsa Studentit i mungon mundësia për të instaluar softuer. Për të shmangur lodhjen e pastrimit të llogarisë Student, kjo llogari thjesht fshihet plotësisht dhe krijohet sërish. Kjo sjell disa veprime që duhet të kryhen në çdo stacion.

Këtë vit vendosa të automatizoj pjesën më të madhe të veprimeve me ndihmën e PowerShell pa Active Directory dhe mbledha në këtë post disa receta që gjeta në internet.

Përgatitja

Menjëherë u ndesha me faktin se në stacione ishte instaluar PS 4 dhe disa shembuj nga interneti allshkurtë nuk punonin. Prandaj, para se të ekzekutoja skriptet e marra, duhej të kryja disa veprime:

  1. Instalo Windows Management Framework 5.1
  2. Instaloni versionin më të fundit PowerShell

Veprime automatizimi

  1. Fshirja/krijimi i llogarisë së përdoruesit
  2. Hyrje automatike e përdoruesit të caktuar
  3. Ekzekutimi i skriptit në hyrjen e parë të përdoruesit

Fshirja/krijimi i llogarisë së përdoruesit

Nisa me krijimin. Në këtë rast kërkohet të kryhen 2 veprime: krijoni përdoruesin (New-LocalUser) dhe shtoni atë në grup (Add-LocalGroupMember). Për lehtësinë, i bashkova këto komanda në një funksion:

Function New-User {
    

    [CmdletBinding()]
    param (
        [PARAMETER(Mandatory=$True)][String]$Name,
        [PARAMETER(Mandatory=$True)][String]$Password
        )

    $Pwd = convertto-securestring $Password -asplaintext -force
    $GroupSID = "S-1-5-32-545"
    New-LocalUser -User $Name -AccountNeverExpires:$true -FullName $Name -Password $Pwd -PasswordNeverExpires:$true
    Add-LocalGroupMember -SID $GroupSID -Member $Name

    Write-Host "-- Përdoruesi $Name është krijuar me fjalëkalimin $Password" -foregroundcolor Green
}

E shtoj në grup përmes SID, sepse në një nga artikujt takova se SID i grupit Përdoruesit është i njëjtë kudo — S-1-5-32-545.

Heqja është organizuar sipas parimeve të mëposhtme: fshij të gjitha llogaritë e krijuara nga Administratori. Për këtë, me ndihmën e objektit WMI të klasës Win32_UserProfile, përcaktoj të gjithë përdoruesit që aktualisht nuk janë aktivë dhe nuk janë speciale.

Function Remove-Users {
    
    [CmdletBinding()]

    $UsersProfiles = Get-WMIObject -class Win32_UserProfile -ComputerName $env:COMPUTERNAME | Where {!($_.Loaded) -and !($_.Special)}
    foreach($Usr in $UsersProfiles) {
       	$UsrName = $Usr.LocalPath.Split("\")[2]
       	Write-Host "-- Heqja e përdoruesit $UsrName ..." -foregroundcolor Green
       	Remove-LocalUser -Name $UsrName
	Remove-WmiObject -Path $Usr.__PATH
        Write-Host "-- Përdoruesi $UsrName u hoq" -foregroundcolor Green
    }
}

Autologin i përdoruesit të caktuar

Këtu gjithçka u kufizua në ndryshimin e regjistrit HKEY_LOCAL_MACHINE. Këto veprime i kam bashkuar gjithashtu në një funksion të vogël:

Function Set-AutoLogon {
    

    [CmdletBinding()]
    param (
        [PARAMETER(Mandatory=$True)][String]$Name,
        [PARAMETER(Mandatory=$True)][String]$Password
        )

    $PathToWinlogon = "HKLM:SoftwareMicrosoftWindows NTCurrentVersionWinlogon"
    New-ItemProperty -Path $PathToWinlogon -Name AutoAdminLogon  -Value 1 -PropertyType "String"
    New-ItemProperty -Path $PathToWinlogon -Name DefaultUserName -Value $Name -PropertyType "String"
    New-ItemProperty -Path $PathToWinlogon -Name DefaultPassword -Value $Password -PropertyType "String"
}

Ekzekutimi i skriptit në hyrjen e parë të përdoruesit

Doli se nuk është e mundur të konfigurohet gjithçka para hyrjes së parë të përdoruesit të ri (çka më befasoi disi). Prandaj, u krijua nevoja për të ekzekutuar një skript që bën disa veprime pas hyrjes së parë:

  1. Konfigurimi i proxy-t
  2. Ndaluar krijimin e skedarëve në desktop
  3. Konfigurimi i panelit të kontrollit të përdoruesit

Kam provuar disa mënyra, por ajo që funksionoi për mua ishte kjo: vendos një detyrë. Por nuk arrita ta krijoj detyrën me mjetet e PS. Prandaj ndoqa një rrugë të gjatë:

schtasks /create /tn LogonUserSettings /tr "pwsh C:ScriptsSettings.ps1" /sc onlogon /ru $env:USERDOMAIN$UserName /rp $Password /f

Por këtë u nevojit një leje shtesë — Windows kërkoi të lejojë hyrjen si një detyrë grupore (SeBatchLogonRight). Kërkimi i një përgjigjeje për këtë shkaktoi një situatë të tillë rezultatit:

LsaWrapper

$Source = @'
using System;
using System.Collections.Generic;
using System.Text;

namespace MyLsaWrapper
{
    using System.Runtime.InteropServices;
    using System.Security;
    using System.Management;
    using System.Runtime.CompilerServices;
    using System.ComponentModel;

    using LSA_HANDLE = IntPtr;

    [StructLayout(LayoutKind.Sequential)]
    struct LSA_OBJECT_ATTRIBUTES
    {
        internal int Length;
        internal IntPtr RootDirectory;
        internal IntPtr ObjectName;
        internal int Attributes;
        internal IntPtr SecurityDescriptor;
        internal IntPtr SecurityQualityOfService;
    }
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    struct LSA_UNICODE_STRING
    {
        internal ushort Length;
        internal ushort MaximumLength;
        [MarshalAs(UnmanagedType.LPWStr)]
        internal string Buffer;
    }
    sealed class Win32Sec
    {
        [DllImport("advapi32", CharSet = CharSet.Unicode, SetLastError = true),
        SuppressUnmanagedCodeSecurityAttribute]
        internal static extern uint LsaOpenPolicy(
        LSA_UNICODE_STRING[] SystemName,
        ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
        int AccessMask,
        out IntPtr PolicyHandle
        );

        [DllImport("advapi32", CharSet = CharSet.Unicode, SetLastError = true),
        SuppressUnmanagedCodeSecurityAttribute]
        internal static extern uint LsaAddAccountRights(
        LSA_HANDLE PolicyHandle,
        IntPtr pSID,
        LSA_UNICODE_STRING[] UserRights,
        int CountOfRights
        );

        [DllImport("advapi32", CharSet = CharSet.Unicode, SetLastError = true),
        SuppressUnmanagedCodeSecurityAttribute]
        internal static extern int LsaLookupNames2(
        LSA_HANDLE PolicyHandle,
        uint Flags,
        uint Count,
        LSA_UNICODE_STRING[] Names,
        ref IntPtr ReferencedDomains,
        ref IntPtr Sids
        );

        [DllImport("advapi32")]
        internal static extern int LsaNtStatusToWinError(int NTSTATUS);

        [DllImport("advapi32")]
        internal static extern int LsaClose(IntPtr PolicyHandle);

        [DllImport("advapi32")]
        internal static extern int LsaFreeMemory(IntPtr Buffer);

    }
    /// <summary>
    /// This class is used to grant "Log on as a service", "Log on as a batchjob", "Log on localy" etc.
    /// to a user.
    /// </summary>
    public sealed class LsaWrapper : IDisposable
    {
        [StructLayout(LayoutKind.Sequential)]
        struct LSA_TRUST_INFORMATION
        {
            internal LSA_UNICODE_STRING Name;
            internal IntPtr Sid;
        }
        [StructLayout(LayoutKind.Sequential)]
        struct LSA_TRANSLATED_SID2
        {
            internal SidNameUse Use;
            internal IntPtr Sid;
            internal int DomainIndex;
            uint Flags;
        }

        [StructLayout(LayoutKind.Sequential)]
        struct LSA_REFERENCED_DOMAIN_LIST
        {
            internal uint Entries;
            internal LSA_TRUST_INFORMATION Domains;
        }

        enum SidNameUse : int
        {
            User = 1,
            Group = 2,
            Domain = 3,
            Alias = 4,
            KnownGroup = 5,
            DeletedAccount = 6,
            Invalid = 7,
            Unknown = 8,
            Computer = 9
        }

        enum Access : int
        {
            POLICY_READ = 0x20006,
            POLICY_ALL_ACCESS = 0x00F0FFF,
            POLICY_EXECUTE = 0X20801,
            POLICY_WRITE = 0X207F8
        }
        const uint STATUS_ACCESS_DENIED = 0xc0000022;
        const uint STATUS_INSUFFICIENT_RESOURCES = 0xc000009a;
        const uint STATUS_NO_MEMORY = 0xc0000017;

        IntPtr lsaHandle;

        public LsaWrapper()
            : this(null)
        { }
        // // local system if systemName is null
        public LsaWrapper(string systemName)
        {
            LSA_OBJECT_ATTRIBUTES lsaAttr;
            lsaAttr.RootDirectory = IntPtr.Zero;
            lsaAttr.ObjectName = IntPtr.Zero;
            lsaAttr.Attributes = 0;
            lsaAttr.SecurityDescriptor = IntPtr.Zero;
            lsaAttr.SecurityQualityOfService = IntPtr.Zero;
            lsaAttr.Length = Marshal.SizeOf(typeof(LSA_OBJECT_ATTRIBUTES));
            lsaHandle = IntPtr.Zero;
            LSA_UNICODE_STRING[] system = null;
            if (systemName != null)
            {
                system = new LSA_UNICODE_STRING[1];
                system[0] = InitLsaString(systemName);
            }

            uint ret = Win32Sec.LsaOpenPolicy(system, ref lsaAttr,
            (int)Access.POLICY_ALL_ACCESS, out lsaHandle);
            if (ret == 0)
                return;
            if (ret == STATUS_ACCESS_DENIED)
            {
                throw new UnauthorizedAccessException();
            }
            if ((ret == STATUS_INSUFFICIENT_RESOURCES) || (ret == STATUS_NO_MEMORY))
            {
                throw new OutOfMemoryException();
            }
            throw new Win32Exception(Win32Sec.LsaNtStatusToWinError((int)ret));
        }

        public void AddPrivileges(string account, string privilege)
        {
            IntPtr pSid = GetSIDInformation(account);
            LSA_UNICODE_STRING[] privileges = new LSA_UNICODE_STRING[1];
            privileges[0] = InitLsaString(privilege);
            uint ret = Win32Sec.LsaAddAccountRights(lsaHandle, pSid, privileges, 1);
            if (ret == 0)
                return;
            if (ret == STATUS_ACCESS_DENIED)
            {
                throw new UnauthorizedAccessException();
            }
            if ((ret == STATUS_INSUFFICIENT_RESOURCES) || (ret == STATUS_NO_MEMORY))
            {
                throw new OutOfMemoryException();
            }
            throw new Win32Exception(Win32Sec.LsaNtStatusToWinError((int)ret));
        }

        public void Dispose()
        {
            if (lsaHandle != IntPtr.Zero)
            {
                Win32Sec.LsaClose(lsaHandle);
                lsaHandle = IntPtr.Zero;
            }
            GC.SuppressFinalize(this);
        }
        ~LsaWrapper()
        {
            Dispose();
        }
        // helper functions

        IntPtr GetSIDInformation(string account)
        {
            LSA_UNICODE_STRING[] names = new LSA_UNICODE_STRING[1];
            LSA_TRANSLATED_SID2 lts;
            IntPtr tsids = IntPtr.Zero;
            IntPtr tdom = IntPtr.Zero;
            names[0] = InitLsaString(account);
            lts.Sid = IntPtr.Zero;
            //Console.WriteLine("String account: {0}", names[0].Length);
            int ret = Win32Sec.LsaLookupNames2(lsaHandle, 0, 1, names, ref tdom, ref tsids);
            if (ret != 0)
                throw new Win32Exception(Win32Sec.LsaNtStatusToWinError(ret));
            lts = (LSA_TRANSLATED_SID2)Marshal.PtrToStructure(tsids,
            typeof(LSA_TRANSLATED_SID2));
            Win32Sec.LsaFreeMemory(tsids);
            Win32Sec.LsaFreeMemory(tdom);
            return lts.Sid;
        }

        static LSA_UNICODE_STRING InitLsaString(string s)
        {
            // Unicode strings max. 32KB
            if (s.Length > 0x7ffe)
                throw new ArgumentException("String too long");
            LSA_UNICODE_STRING lus = new LSA_UNICODE_STRING();
            lus.Buffer = s;
            lus.Length = (ushort)(s.Length * sizeof(char));
            lus.MaximumLength = (ushort)(lus.Length + sizeof(char));
            return lus;
        }
    }
    public class LsaWrapperCaller
    {
        public static void AddPrivileges(string account, string privilege)
        {
            using (LsaWrapper lsaWrapper = new LsaWrapper())
            {
                lsaWrapper.AddPrivileges(account, privilege);
            }
        }
    }
}
'@

Add-Type -TypeDefinition $Source
[MyLsaWrapper.LsaWrapperCaller]::AddPrivileges($Identity, "SeBatchLogonRight")

Leja për të hyrë si një detyrë grupore lejonte të avancoja më tej — për të shkruar një skenar që ekzekutohet nga përdoruesi.

Konfigurimi i proxy-t

Me konfigurimin e proxy ishte një gjë shumë e thjeshtë. Zgjidhja funksionale u gjet shpejt:

Function Set-Proxy {
    

    [CmdletBinding()]
    param (
        [PARAMETER(Mandatory=$True)][String]$Server,
        [PARAMETER(Mandatory=$True)][Int]$Port
        )

    If ((Test-NetConnection -ComputerName $Server -Port $Port).TcpTestSucceeded) {
        Set-ItemProperty -Path 'HKCU:SoftwareMicrosoftWindowsCurrentVersionInternet Settings' -name ProxyServer -Value "$($Server):$($Port)"
        Set-ItemProperty -Path 'HKCU:SoftwareMicrosoftWindowsCurrentVersionInternet Settings' -name ProxyEnable -Value 1
    } Else {
        Write-Error -Message "-- Adresa e serverit të proxy ose porta është e pavlefshme:  $($Server):$($Port)"
    }
}

Ndaluar krijimin e skedarëve në desktop

Me ndalimin e krijimit të skedave në desktop, më duhej të merrem me të për më gjatë se me rrjetin. Të përcaktoja të drejtat për dosjen nuk ishte aq e thjeshtë si në sistemet *nix. Por edhe këtu u gjetën përgjigje, të cilat i adaptoja me sukses për veten time:

Funksioni Set-AccessRule {
    <#
    .SYNOPSIS
        Vendosja e të drejtave në dosje
    .DESCRIPTION
        Ky funksion vendos të drejtat e caktuara mbi një drejtor
    .EXAMPLE
        #Set-AccessRule -Folder $env:USERPROFILEDesktop  -UserName $env:USERNAME -Rules CreateFiles,AppendData -AccessControlType Deny
    .PARAMETER Folder
        Drejtoria mbi të cilën kryhet veprimi (parametër i detyrueshëm)
    .PARAMETER UserName
        Emri i llogarisë së përdoruesit, për të cilin vendosen të drejtat e aksesit (parametër i detyrueshëm)
    .PARAMETER Rules
        Të drejtat e aksesit të ndara me presje (parametër i detyrueshëm)
    .PARAMETER AccessControlType
        Parametër i detyrueshëm, i cili mund të marrë njërin nga dy vlerat: Allow ose Deny
    #>
    [CmdletBinding()]
    param (
        [PARAMETER(Mandatory=$True)][Path]$Folder,
        [PARAMETER(Mandatory=$True)][String]$UserName,
        [PARAMETER(Mandatory=$True)][String]$Rules,
        [PARAMETER(Mandatory=$True)][String]$AccessControlType
        )

    #lexojmë listën aktuale të ACL të desktopit
    $acl = Get-Acl $Folder
    #Krijojmë një variabël me të drejtat e nevojshme
    $fileSystemRights = [System.Security.AccessControl.FileSystemRights]"$Rules"
    #Krijojmë një variabël me emrin e përdoruesit, të drejtat e aksesit dhe llojin e lejes
    $AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($UserName, $fileSystemRights, $AccessControlType)
    #Kalim i variablës tek klasa FileSystemAccessRule për të krijuar një objekt
    $acl.SetAccessRule($AccessRule)
    #Aplikojmë lejet në dosje
    $acl | Set-Acl $Folder
}

Set-AccessRule -Folder $env:USERPROFILEDesktop  -UserName $env:USERNAME -Rules CreateFiles,AppendData,Delete -AccessControlType Deny

Përshkrimi i FileSystemRights në zyrën zyrtare website.

Konfigurimi i panelit të kontrollit të përdoruesit

Kjo nuk ishte e nevojshme, por mendova se do të ishte cool t'u ofroja studentëve një panel të konfigurueshëm, me programet e përdorura shpesh. Një përgjigje u gjet këtu.

Aplikacioni i ngulitur

funksioni Set-PinnedApplication
{
    
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$True)][String]$Action, 
        [Parameter(Mandatory=$True)][String]$FilePath
    )
    if(-not (test-path $FilePath)) { 
        throw "FilePath nuk ekziston."  
    }
    function InvokeVerb {
        param([string]$FilePath,$verb)
        $verb = $verb.Replace("&","")
        $path = split-path $FilePath
        $shell = new-object -com "Shell.Application" 
        $folder = $shell.Namespace($path)   
        $item = $folder.Parsename((split-path $FilePath -leaf))
        $itemVerb = $item.Verbs() | ? {$_.Name.Replace("&","") -eq $verb}
        if($itemVerb -eq $null){
            throw "Veprimi $verb nuk u gjet."			
        } else {
            $itemVerb.DoIt()
        }
    }
    function GetVerb {
        param([int]$verbId)
        try {
            $t = [type]"CosmosKey.Util.MuiHelper"
        } catch {
            $def = [Text.StringBuilder]""
            [void]$def.AppendLine('[DllImport("user32.dll")]')
            [void]$def.AppendLine('public static extern int LoadString(IntPtr h,uint id, System.Text.StringBuilder sb,int maxBuffer);')
            [void]$def.AppendLine('[DllImport("kernel32.dll")]')
            [void]$def.AppendLine('public static extern IntPtr LoadLibrary(string s);')
            Add-Type -MemberDefinition $def.ToString() -name MuiHelper -namespace CosmosKey.Util			
        }
        if($global:CosmosKey_Utils_MuiHelper_Shell32 -eq $null){		
            $global:CosmosKey_Utils_MuiHelper_Shell32 = [CosmosKey.Util.MuiHelper]::LoadLibrary("shell32.dll")
        }
        $maxVerbLength=255
        $verbBuilder = New-Object Text.StringBuilder "",$maxVerbLength
        [void][CosmosKey.Util.MuiHelper]::LoadString($CosmosKey_Utils_MuiHelper_Shell32,$verbId,$verbBuilder,$maxVerbLength)
        return $verbBuilder.ToString()
    }
    $verbs = @{ 
        "PintoTaskbar"=5386
        "UnpinfromTaskbar"=5387
    }
    if($verbs.$Action -eq $null){
        Throw "Veprimi $action nuk mbështetet`nVeprimet e mbështetura janë:`n`tPintoTaskbar`n`tUnpinfromTaskbar"
    }
    InvokeVerb -FilePath $FilePath -Verb $(GetVerb -VerbId $verbs.$action)
}

Përfundim

Skripti po funksionon, koha e mirëmbajtjes për secilën stacion ka rënë, qëllimi është arritur. Për mua, si përdorues i Linux, konfigurimi i Windows u duk si një përvojë e vështirë, por edukative. Do ta zhvilloj skriptin e konfigurimit. Kam në plan të shtoj kontrollin e pranisë së softuerit të instaluar dhe instalimin, aktivizimin e antivirusit.

Skriptet përfundimtare, të cilat janë në punë

Ekzekutimi si Administrator

Function New-User {
    <#
    .SYNOPSIS
        Создание нового пользователя
    .DESCRIPTION
        Данная функция создает нового пользователя и добавляет его в группу Пользователи
    .EXAMPLE
        #New-User "Student" "Student"
    .PARAMETER Name
        Имя нового пользователя (обязательный параметр)
    .PARAMETER Password
        Пароль (обязательный параметр)
    #>

    [CmdletBinding()]
    param (
        [PARAMETER(Mandatory=$True)][String]$Name,
        [PARAMETER(Mandatory=$True)][String]$Password
        )

    $Pwd = convertto-securestring $Password -asplaintext -force
    $GroupSID = "S-1-5-32-545"
    New-LocalUser -User $Name -AccountNeverExpires:$true -FullName $Name -Password $Pwd -PasswordNeverExpires:$true
    Add-LocalGroupMember -SID $GroupSID -Member $Name

    Write-Host "-- Создан пользователь $Name с паролем $Password" -foregroundcolor Green
}

Function Remove-Users {
    <#
    .SYNOPSIS
        Удаление пользователей
    .DESCRIPTION
        Данная функция удаляет пользователей, которые сейчас не активны и не являются специальными
        Удаляются в том числе рабочий каталог и реестр пользователей
    .EXAMPLE
        #Remove-Users
    #>
    [CmdletBinding()]

    $UsersProfiles = Get-WMIObject -class Win32_UserProfile -ComputerName $env:COMPUTERNAME | Where {!($_.Loaded) -and !($_.Special)}
	foreach($Usr in $UsersProfiles) {
        $UsrName = $Usr.LocalPath.Split("")[2]
        Write-Host "-- Удаление пользователя $UsrName ..." -foregroundcolor Green
        Remove-LocalUser -Name $UsrName
		Remove-WmiObject -Path $Usr.__PATH
        Write-Host "-- Пользователь $UsrName удален" -foregroundcolor Green
	}
}

Function Set-AutoLogon {
    <#
    .SYNOPSIS
        Включение автовхода для пользователя
    .DESCRIPTION
        Данная функция включает автовход для указанного пользователя
    .EXAMPLE
        #Set-AutoLogon  "Student" "Student"
    .PARAMETER Name
        Имя пользователя (обязательный параметр)
    .PARAMETER Password
        Пароль (обязательный параметр)
    #>

    [CmdletBinding()]
    param (
        [PARAMETER(Mandatory=$True)][String]$Name,
        [PARAMETER(Mandatory=$True)][String]$Password
        )

    $PathToWinlogon = "HKLM:SoftwareMicrosoftWindows NTCurrentVersionWinlogon"
    New-ItemProperty -Path $PathToWinlogon -Name AutoAdminLogon  -Value 1 -PropertyType "String"
    New-ItemProperty -Path $PathToWinlogon -Name DefaultUserName -Value $Name -PropertyType "String"
    New-ItemProperty -Path $PathToWinlogon -Name DefaultPassword -Value $Password -PropertyType "String"
}

$Source = @'
using System;
using System.Collections.Generic;
using System.Text;

namespace MyLsaWrapper
{
    using System.Runtime.InteropServices;
    using System.Security;
    using System.Management;
    using System.Runtime.CompilerServices;
    using System.ComponentModel;

    using LSA_HANDLE = IntPtr;

    [StructLayout(LayoutKind.Sequential)]
    struct LSA_OBJECT_ATTRIBUTES
    {
        internal int Length;
        internal IntPtr RootDirectory;
        internal IntPtr ObjectName;
        internal int Attributes;
        internal IntPtr SecurityDescriptor;
        internal IntPtr SecurityQualityOfService;
    }
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    struct LSA_UNICODE_STRING
    {
        internal ushort Length;
        internal ushort MaximumLength;
        [MarshalAs(UnmanagedType.LPWStr)]
        internal string Buffer;
    }
    sealed class Win32Sec
    {
        [DllImport("advapi32", CharSet = CharSet.Unicode, SetLastError = true),
        SuppressUnmanagedCodeSecurityAttribute]
        internal static extern uint LsaOpenPolicy(
        LSA_UNICODE_STRING[] SystemName,
        ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
        int AccessMask,
        out IntPtr PolicyHandle
        );

        [DllImport("advapi32", CharSet = CharSet.Unicode, SetLastError = true),
        SuppressUnmanagedCodeSecurityAttribute]
        internal static extern uint LsaAddAccountRights(
        LSA_HANDLE PolicyHandle,
        IntPtr pSID,
        LSA_UNICODE_STRING[] UserRights,
        int CountOfRights
        );

        [DllImport("advapi32", CharSet = CharSet.Unicode, SetLastError = true),
        SuppressUnmanagedCodeSecurityAttribute]
        internal static extern int LsaLookupNames2(
        LSA_HANDLE PolicyHandle,
        uint Flags,
        uint Count,
        LSA_UNICODE_STRING[] Names,
        ref IntPtr ReferencedDomains,
        ref IntPtr Sids
        );

        [DllImport("advapi32")]
        internal static extern int LsaNtStatusToWinError(int NTSTATUS);

        [DllImport("advapi32")]
        internal static extern int LsaClose(IntPtr PolicyHandle);

        [DllImport("advapi32")]
        internal static extern int LsaFreeMemory(IntPtr Buffer);

    }
    /// <summary>
    /// This class is used to grant "Log on as a service", "Log on as a batchjob", "Log on localy" etc.
    /// to a user.
    /// </summary>
    public sealed class LsaWrapper : IDisposable
    {
        [StructLayout(LayoutKind.Sequential)]
        struct LSA_TRUST_INFORMATION
        {
            internal LSA_UNICODE_STRING Name;
            internal IntPtr Sid;
        }
        [StructLayout(LayoutKind.Sequential)]
        struct LSA_TRANSLATED_SID2
        {
            internal SidNameUse Use;
            internal IntPtr Sid;
            internal int DomainIndex;
            uint Flags;
        }

        [StructLayout(LayoutKind.Sequential)]
        struct LSA_REFERENCED_DOMAIN_LIST
        {
            internal uint Entries;
            internal LSA_TRUST_INFORMATION Domains;
        }

        enum SidNameUse : int
        {
            User = 1,
            Group = 2,
            Domain = 3,
            Alias = 4,
            KnownGroup = 5,
            DeletedAccount = 6,
            Invalid = 7,
            Unknown = 8,
            Computer = 9
        }

        enum Access : int
        {
            POLICY_READ = 0x20006,
            POLICY_ALL_ACCESS = 0x00F0FFF,
            POLICY_EXECUTE = 0X20801,
            POLICY_WRITE = 0X207F8
        }
        const uint STATUS_ACCESS_DENIED = 0xc0000022;
        const uint STATUS_INSUFFICIENT_RESOURCES = 0xc000009a;
        const uint STATUS_NO_MEMORY = 0xc0000017;

        IntPtr lsaHandle;

        public LsaWrapper()
            : this(null)
        { }
        // // local system if systemName is null
        public LsaWrapper(string systemName)
        {
            LSA_OBJECT_ATTRIBUTES lsaAttr;
            lsaAttr.RootDirectory = IntPtr.Zero;
            lsaAttr.ObjectName = IntPtr.Zero;
            lsaAttr.Attributes = 0;
            lsaAttr.SecurityDescriptor = IntPtr.Zero;
            lsaAttr.SecurityQualityOfService = IntPtr.Zero;
            lsaAttr.Length = Marshal.SizeOf(typeof(LSA_OBJECT_ATTRIBUTES));
            lsaHandle = IntPtr.Zero;
            LSA_UNICODE_STRING[] system = null;
            if (systemName != null)
            {
                system = new LSA_UNICODE_STRING[1];
                system[0] = InitLsaString(systemName);
            }

            uint ret = Win32Sec.LsaOpenPolicy(system, ref lsaAttr,
            (int)Access.POLICY_ALL_ACCESS, out lsaHandle);
            if (ret == 0)
                return;
            if (ret == STATUS_ACCESS_DENIED)
            {
                throw new UnauthorizedAccessException();
            }
            if ((ret == STATUS_INSUFFICIENT_RESOURCES) || (ret == STATUS_NO_MEMORY))
            {
                throw new OutOfMemoryException();
            }
            throw new Win32Exception(Win32Sec.LsaNtStatusToWinError((int)ret));
        }

        public void AddPrivileges(string account, string privilege)
        {
            IntPtr pSid = GetSIDInformation(account);
            LSA_UNICODE_STRING[] privileges = new LSA_UNICODE_STRING[1];
            privileges[0] = InitLsaString(privilege);
            uint ret = Win32Sec.LsaAddAccountRights(lsaHandle, pSid, privileges, 1);
            if (ret == 0)
                return;
            if (ret == STATUS_ACCESS_DENIED)
            {
                throw new UnauthorizedAccessException();
            }
            if ((ret == STATUS_INSUFFICIENT_RESOURCES) || (ret == STATUS_NO_MEMORY))
            {
                throw new OutOfMemoryException();
            }
            throw new Win32Exception(Win32Sec.LsaNtStatusToWinError((int)ret));
        }

        public void Dispose()
        {
            if (lsaHandle != IntPtr.Zero)
            {
                Win32Sec.LsaClose(lsaHandle);
                lsaHandle = IntPtr.Zero;
            }
            GC.SuppressFinalize(this);
        }
        ~LsaWrapper()
        {
            Dispose();
        }
        // helper functions

        IntPtr GetSIDInformation(string account)
        {
            LSA_UNICODE_STRING[] names = new LSA_UNICODE_STRING[1];
            LSA_TRANSLATED_SID2 lts;
            IntPtr tsids = IntPtr.Zero;
            IntPtr tdom = IntPtr.Zero;
            names[0] = InitLsaString(account);
            lts.Sid = IntPtr.Zero;
            //Console.WriteLine("String account: {0}", names[0].Length);
            int ret = Win32Sec.LsaLookupNames2(lsaHandle, 0, 1, names, ref tdom, ref tsids);
            if (ret != 0)
                throw new Win32Exception(Win32Sec.LsaNtStatusToWinError(ret));
            lts = (LSA_TRANSLATED_SID2)Marshal.PtrToStructure(tsids,
            typeof(LSA_TRANSLATED_SID2));
            Win32Sec.LsaFreeMemory(tsids);
            Win32Sec.LsaFreeMemory(tdom);
            return lts.Sid;
        }

        static LSA_UNICODE_STRING InitLsaString(string s)
        {
            // Unicode strings max. 32KB
            if (s.Length > 0x7ffe)
                throw new ArgumentException("String too long");
            LSA_UNICODE_STRING lus = new LSA_UNICODE_STRING();
            lus.Buffer = s;
            lus.Length = (ushort)(s.Length * sizeof(char));
            lus.MaximumLength = (ushort)(lus.Length + sizeof(char));
            return lus;
        }
    }
    public class LsaWrapperCaller
    {
        public static void AddPrivileges(string account, string privilege)
        {
            using (LsaWrapper lsaWrapper = new LsaWrapper())
            {
                lsaWrapper.AddPrivileges(account, privilege);
            }
        }
    }
}
'@

Add-Type -TypeDefinition $Source | Out-Null


# -------------------------
# Пересоздание пользователя
# -------------------------
$UserName    = "Student"
$Password    = "Student"

Remove-Users | Out-Null
New-User $UserName $Password | Out-Null
Set-AutoLogon $UserName $Password | Out-Null
[MyLsaWrapper.LsaWrapperCaller]::AddPrivileges($UserName, "SeBatchLogonRight") | Out-Null
write-host "-- разрешен вход в качестве пакетного задания для пользователя $UserName" -foregroundcolor Green
schtasks /create /tn LogonUserSettings /tr "pwsh C:ScriptsSetupUser.ps1" /sc onlogon /ru $env:USERDOMAIN$UserName /rp $Password /f

Ekzekutuar nga përdoruesi Student

Funksioni Set-Proxy {
    

    [CmdletBinding()]
    param (
        [PARAMETER(Mandatory=$True)][String]$Server,
        [PARAMETER(Mandatory=$True)][Int]$Port
        )

	If ((Test-NetConnection -ComputerName $Server -Port $Port).TcpTestSucceeded) {
		Set-ItemProperty -Path 'HKCU:SoftwareMicrosoftWindowsCurrentVersionInternet Settings' -name ProxyServer -Value "$($Server):$($Port)"
		Set-ItemProperty -Path 'HKCU:SoftwareMicrosoftWindowsCurrentVersionInternet Settings' -name ProxyEnable -Value 1
	} Else {
		Write-Error -Message "-- Adresa e serverit ose porta e proxy është e pavlefshme:  $($Server):$($Port)"
	}
}

Funksioni Set-AccessRule {
    
    [CmdletBinding()]
    param (
        [PARAMETER(Mandatory=$True)][String]$Folder,
        [PARAMETER(Mandatory=$True)][String]$UserName,
        [PARAMETER(Mandatory=$True)][String]$Rules,
        [PARAMETER(Mandatory=$True)][String]$AccessControlType
        )

    # Lexojmë listën aktuale ACL të desktop-it
    $acl = Get-Acl $Folder
    # Krijojmë një variabël me drejtat e nevojshme
    $fileSystemRights = [System.Security.AccessControl.FileSystemRights]"$Rules"
    # Krijojmë një variabël me specifikimin e përdoruesit, të drejtave të aksesit dhe llojit të lejes
    $AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($UserName, $fileSystemRights, $AccessControlType)
    # Transferojmë variablën në klasën FileSystemAccessRule për të krijuar një objekt
    $acl.SetAccessRule($AccessRule)
    # Aplikojmë lejet në dosje
    $acl | Set-Acl $Folder
}

function Set-PinnedApplication
{
    
    [CmdletBinding()]
    param(
            [Parameter(Mandatory=$True)][String]$Action, 
            [Parameter(Mandatory=$True)][String]$FilePath
    )
    if(-not (test-path $FilePath)) { 
        throw "FilePath nuk ekziston."  
    }
    function InvokeVerb {
        param([string]$FilePath,$verb)
        $verb = $verb.Replace("&","")
        $path = split-path $FilePath
        $shell = new-object -com "Shell.Application" 
        $folder = $shell.Namespace($path)   
        $item = $folder.Parsename((split-path $FilePath -leaf))
        $itemVerb = $item.Verbs() | ? {$_.Name.Replace("&","") -eq $verb}
        if($itemVerb -eq $null){
            throw "Veprimi $verb nuk u gjet."           
        } else {
            $itemVerb.DoIt()
        }
    }
    function GetVerb {
        param([int]$verbId)
        try {
            $t = [type]"CosmosKey.Util.MuiHelper"
        } catch {
            $def = [Text.StringBuilder]""
            [void]$def.AppendLine('[DllImport("user32.dll")]')
            [void]$def.AppendLine('public static extern int LoadString(IntPtr h,uint id, System.Text.StringBuilder sb,int maxBuffer);')
            [void]$def.AppendLine('[DllImport("kernel32.dll")]')
            [void]$def.AppendLine('public static extern IntPtr LoadLibrary(string s);')
            Add-Type -MemberDefinition $def.ToString() -name MuiHelper -namespace CosmosKey.Util            
        }
        if($global:CosmosKey_Utils_MuiHelper_Shell32 -eq $null){        
            $global:CosmosKey_Utils_MuiHelper_Shell32 = [CosmosKey.Util.MuiHelper]::LoadLibrary("shell32.dll")
        }
        $maxVerbLength=255
        $verbBuilder = New-Object Text.StringBuilder "",$maxVerbLength
        [void][CosmosKey.Util.MuiHelper]::LoadString($CosmosKey_Utils_MuiHelper_Shell32,$verbId,$verbBuilder,$maxVerbLength)
        return $verbBuilder.ToString()
    }
    $verbs = @{ 
        "PintoTaskbar"=5386
        "UnpinfromTaskbar"=5387
    }
    if($verbs.$Action -eq $null){
        Throw "Veprimi $action nuk mbështetet`nVeprimet e mbështetura janë:`n`tPintoTaskbar`n`tUnpinfromTaskbar"
    }
    InvokeVerb -FilePath $FilePath -Verb $(GetVerb -VerbId $verbs.$action)
}

Set-Proxy cproxy.udsu.ru 8080
Set-AccessRule -Folder $env:USERPROFILEDesktop  -UserName $env:USERNAME -Rules "CreateFiles,AppendData,Delete" -AccessControlType Deny

Set-PinnedApplication -Action UnpinfromTaskbar -FilePath "$env:ProgramFilesInternet Exploreriexplore.exe"
Set-PinnedApplication -Action PintoTaskbar -FilePath "${env:ProgramFiles(x86)}Mozilla Firefoxfirefox.exe"
Set-PinnedApplication -Action PintoTaskbar -FilePath "$env:ProgramDataMicrosoftWindowsStart MenuProgramsMicrosoft Office 2013Excel 2013.lnk"
Set-PinnedApplication -Action PintoTaskbar -FilePath "$env:ProgramDataMicrosoftWindowsStart MenuProgramsMicrosoft Office 2013Word 2013.lnk"
Set-PinnedApplication -Action PintoTaskbar -FilePath "$env:ProgramDataMicrosoftWindowsStart MenuProgramsMicrosoft Office 2013PowerPoint 2013.lnk"
Set-PinnedApplication -Action PintoTaskbar -FilePath "$env:ProgramDataMicrosoftWindowsStart MenuProgramsАСКОНКОМПАС-3D V16КОМПАС-3D V16.lnk"

# Heqja e detyrës, pas përfundimit të saj
Unregister-ScheduledTask -TaskName UdSUSettingStudent -Confirm:$false

Burimi: habr.com

Blini hosting të besueshëm për faqe interneti me mbrojtje nga DDoS, serverë VPS VDS 🔥 Blini hosting të besueshëm për faqe interneti me mbrojtje nga DDoS, serverë VPS VDS | ProHoster