Kristoffer Qvists blogg om allt möjligt

Kategori: Programmering och scripting

Innehåll som handlar om programmering och att skriva script.

LaTeX – ett annorlunda sätt att skriva dokument

Om du är IT-intresserad, eller akademiker kanske du redan har hört talas om LaTeX. För den som inte vet så är LaTeX ett typsättningssystem, allt ifrån matematiska formler till olika typer av dokument och presentationer. Tjusningen med systemet är att man slipper tänka på formateringen i ett WYSIWYG-system och istället fokusera på innehållet.

Man skulle kunna säga att man skriver ett märkspråk som omgiver det textinnehåll som man vill författa. Genom att göra på så sätt så behöver man inte lägga någon fokus kring designen av dokumentet. Programmet kommer att göra detta automatiskt åt en.

Man även programmera i TeX, dock har jag själv inte gjort det i en större utsträckning. Men det kan dock finnas tillfällen då jag kan se en viss nytta med detta. Ett exempel är dokument som i princip har samma utformning med enstaka skillnader.

Exempel av LaTeX-dokument

Ett exempel på LaTeX-kod kan se ut enligt nedan:

% Procenttecken anger kommentar i LaTeX-koden
% Först anger vi dokumentklass, och att vi använder A4-format
\documentclass[a4paper]{article}

% Därefter hämtar vi paket som vi kommer använda oss utav
% Vi hämtar ett svenskt språkpaket
\usepackage[swedish]{babel}
% Vi anger också att vi gärna vill ha UTF-8-kodning
\usepackage[utf8]{inputenc}

% Titel för dokumentet
\title{Dokumenttitel}
% Författare
\author{Författare}
% Man kan specifiera datum inuti måsvingarna nedan och avkommentera den raden. Annars
% kommer datumet för genereringen av dokumentet att visas.
%\date{}

% Nu börjar vi med dokumentet
\begin{document}
	% Kommandot nedan genererar titel, författare och datum på första sidan
	\maketitle{}
	
	% Nu börjar vi med ett element som skall centreras i dokumentet
	\begin{center}
		% Låt oss skapa en tabell med två kolumner där texten är vänsterjusterad
		% med lodräta linjer emellan raderna.
		\begin{tabular}{ |l|l| } \hline
			
			% & skiljer raderna åt och \\ skapar en ny rad
			A & B \\ \hline
			1 & 2 \\ \hline
		\end{tabular}
	\end{center}
	
	Därefter tar vi och skriver lite paragrafer för skojs skull.  Löksås ipsum färdväg söka när kanske enligt själv genom i ta vi ännu miljoner blivit har, att lax mjuka hans sig gamla söka bland omfångsrik vi det annat sorgliga. Häst omfångsrik dimmhöljd som dock räv händer vad om denna och, av där det tid enligt det sällan vad kom där sista, groda rot från rännil söka om ordningens gamla sista.
	
	Samtidigt och inom mot stora vemod dag om blivit ordningens, och rot verkligen bra lax fram och har, ta att själv se så ser regn sax. Nu att ingalunda stig smultron verkligen har brunsås göras, vidsträckt stora för gör färdväg varit ordningens, vi från i gamla kom plats dag. Regn söka ser själv helt mot gamla kom bra kanske, sällan kan flera och hans regn rot därmed, mot ska hela äng oss redan år verkligen.
	
	Ingalunda ordningens kanske dag precis fram faktor annan söka inom sax, blivit olika flera ser räv tiden stora hela därmed. Groda stig om kanske mjuka miljoner, groda tidigare vi hans sax omfångsrik, gör år räv när. Det om icke samtidigt sista är för gör det dunge, själv ingalunda räv precis sin vidsträckt annat ordningens gamla har, ännu stora händer flera från groda hela verkligen.
	
	Gamla åker trevnadens både helt söka se åker mjuka annat kanske det kom trevnadens strand sjö, kunde kom verkligen äng hela precis miljoner groda erfarenheter brunsås rot söka blivit flera. Blivit samma smultron tid nu kunde bra äng, samma kanske inom där från det sjö, nya bra häst tid som ser. 
\end{document}

Texten ovan kommer att generera något i stil med bilden nedan.

Dock är exemplet mycket enkelt och kanske inte väldigt användbart i sin enkelhet. Däremot när man kombinerar olika delar av LaTeX och utökar dess funktionalitet så lyser den. Därför används den bland annat då man skriver vetenskapliga rapporter och artiklar. Det är även användbart då man vill skriva böcker.

Andra exempel

Något som jag ser som “typiskt svenskt” är just dagordningar och protokoll för möten. Man kan ha löpande numrering i protokoll under ett år. Mallar som jag har hittat har inte passat mitt tycke. Bland dessa är en enkel mall för LaTeX och paketet “Minutes“. I slutändan skrev jag en egen mall som jag kan uppdatera allt eftersom.

Exempel av protokoll för styrelsemöte

Exemplet nedan är utformat efter min egna mall. För att det ska fungera så behövs en logotyp med “Logo.png” i samma mapp som .tex-filen finns. Saknar man logga så kan raden \fancyhead[L]{\includegraphics[height=24pt]{Logo.png}} kommenteras bort.

\documentclass[a4paper]{article}

%%%%% Först börjar vi med dokumentinställningarna %%%%%

% Importera viktiga paket till dokumentet
\usepackage[swedish]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{titling}

\usepackage[shortlabels]{enumitem}
\usepackage{hyperref}

\usepackage{graphicx}
\usepackage{fancyhdr}

% Importera typsnitt
\usepackage{tgbonum}

\usepackage[textwidth=17cm, bottom=2cm]{geometry}

% Dokumenttitel med organisation och datum
\title{\textbf{Dagordning styrelsemöte}}
\author{\textbf{Organisation}}
\date{20 juli 2020}

\renewcommand{\rmdefault}{ptm}
\renewcommand{\sfdefault}{ptm}

% Används för att få till loggan snyggt i dokumentet
\pagestyle{plain}
\renewcommand{\headrulewidth}{0pt}
\fancyhead[L]{\includegraphics[height=24pt]{Logo.png}}

% Ange mötesnummer nedan
\newcommand\meetingNumber{1}
% Kom ihåg att lägga i sista paragrafnummer från föregående protokoll.
% Skall dagordningen däremot börja på 1, skriv noll nedan.
\newcommand\previousLastParagraphNumber{0}
\newcommand\location{Plats}
% Justerare för mötet
\newcommand\minutesChecker{Anders Andersson}

%%%%% Nu skapar vi dokumentet %%%%%
\begin{document}
	% Säger åt TeX att använda ett Arial-liknande typsnitt
	\fontfamily{phv}\selectfont
	\maketitle{}
	\thispagestyle{fancy}
	
	% Säger åt LaTeX att använda ett "Times"-typsnitt härifrån
	\fontfamily{ptm}\selectfont
	
	% Information om styrelsen, för kännedom m.m.
	\begin{center}
		\begin{tabular}{ |l|l| } \hline
			Möte nummer & \meetingNumber \\	\hline
			% Omfång skapas automatiskt. Gå ned till "öppnande av mötet" för att ändra första punkt
			Omfång & \ref{FirstItem} -- \ref{LastItem}  \\ \hline
			Plats & \location \\ \hline
			Styrelsen & Sven Svensson \\
			& Johan Johansson \\
			& \minutesChecker \\ \hline
			Anmält förhinder & Erik Eriksson \\ \hline
			Gäst & \\ \hline
			För kännedom & Emma Andersson \\
			& Emma Johansson \\ \hline
		\end{tabular}
	\end{center}
	
	\begin{enumerate}[label={§ \arabic*}]\bfseries
		\setcounter{enumi}{\previousLastParagraphNumber}
		
		% \label{FirstItem} innebär att omfångets första nummer ges till \ref{FirstItem} under omfång
		\item\label{FirstItem} Öppnande av mötet
		
		\item Godkännande av dagordning
		
		\item Val av protokolljusterare \\
		\textmd{Förslag: \minutesChecker.}
		
		\item Godkännande av dagordning
		
		\item Föregående protokoll
		
		\item Mötespunkt
		
		\item Övriga frågor
		
		\item Nästa möte \\
		\textmd{Den 15 oktober.}
		
		\item\label{LastItem} Mötets avslutande
		
	\end{enumerate}
\end{document}

Ovan text genererar i slutändan nedan dokument. De röda boxarna visas enbart i PDF-läsare men inte i utskrivna dokument. De röda boxarna är referenser till paragraferna med samma nummer.

Om du finner exemplet användbart, så får du ta och göra vad du vill med det.

Latex-program

Jag vill gärna tipsa om två program; MikTeX samt TeXstudio. Båda program kan användas i en Windows-miljö. TeXstudio kan användas av andra operativsystem också.

MikTeX är ett verktyg för att installera på ett enkelt sätt installera TeX-paket. TeXstudio å sin sida kan användas för att skapa .PDF-dokument av .tex-filer.

NextCloud – lovande, men kan förbättras

Det är nog inte en hemlighet att jag är en anhängare av fri programvara och öppen källkod. Jag anser att de programmen bidrar väldigt mycket till samhället. Ibland upplever jag att projekten lovar kanske något över förväntan. Ibland kan orsaken också vara mindre bra dokumentation.

NextCloud är på ett sätt en konkurrent till Microsoft Office 365. Det kan centralt, på ens egna server, lagra filer. Man kan dela filerna och även modifiera dem i exempelvis ett ordbehandlingsprogram på servern. Dessutom finns möjlighet att lägga till appar, såsom chatt- och konferensappar.

Problemen som jag har upplevt har varit att dokumentationen varit något spretig. Ibland har felkonfigurationer uppdagats först vid “skarpt läge”, därför att dokumentationen har varit otydlig med uppsättningen. Jag förstår att man vill visa möjligheterna – men det får inte ske på bekostnad av att ha otydlig dokumentation.

Stöd för “Office”-programvara i webbläsaren

NextCloud har stöd kontorsprogram som kan öppnas i Webbläsaren. Idag stöds två olika valmöjligheter, både Collabora Online och OnlyOffice. Det tidigare alternativet är en online-variant av LibreOffice, och det senare en “Microsoft Office”-lik produkt.

Jag är kluven mellan OnlyOffice och Collabora Online som verktyg. Jag upplever OnlyOffice som mer estetiskt tilltalande. Samtidigt upplever jag Collabora Online mer som ett sant alternativ för “fri mjukvara” – även om OnlyOffice erbjuds med AGPL-licensen. Orsaken är att OnlyOffice har ett hårdkodat tak med maximalt 20 samtidiga öppna dokument.

Collabora Online upplever jag som mindre estetiskt tilltalande. Samtidigt är det även mer krångligt att sätta upp för NextCloud då en separat dokumentserver krävs. Man kan idag, via appar i NextCloud, få igång OnlyOffice.

Videokonferenser med Talk

NextCloud stödjer videokonferenser med Talk. Dock har det inte varit tydligt hur man sätter upp dessa. Istället hänvisas man till forumtrådar om att konfigurera stöd för videokonferens i Talk. Eller så får man läsa utvecklardokumentationen istället för administrationsdokumentationen.

Det största problemet är om man har server bakom en NAT – Network Address Translation – så behöver man konfigurera NextCloud ytterligare. Enkelt förklarat delar NAT på en publik IP-adress för fler enheter*. Idag är det vanligt i IPv4-nätverk på grund av att det finns ett begränsat antal IPv4-adresser.

Det som krävs är en “TURN”-server. TURN står för “Traversal Using Relays around NAT” och hjälper till då Nextcloud – och även klienten är bakom en NAT.

Det viktiga är också att en specifik nätverksport i servern är öppen – för att stödja TURN. Denna port ska även vidarebefodras från routern som är värd för NAT:en.

Slutsats

Trots vissa tillkortakommanden, så tycker jag att NextCloud är ett bra alternativ. Det finns ett aktivt team som arbetar med att förbättra mjukvaran. Samtidigt erbjuds även företagssupport av dessa program, varifrån projektet får sin finansiering.

*Tekniskt sett heter detta egentligen PAT, eller “Port Address Translation”.

Förbättra hemsidans SEO – eller relevans hos sökmotorer

För att ens hemsida skall synas på Google, Bing och andra sökmotorer bör man ha en kommunikationsstrategi med den. Två viktiga frågor som man bör ställa sig är ”vad vill jag förmedla”, samt ”vad gör min sajt unik”. Därefter bör man utforma webbsajten utifrån svaren.

1. Håll dig uppdaterad vad gäller bästa praxis (best practice)

Bästa praxis är något som kan skilja sig från år till år. På nätet kan man finna många guider kring SEO, eller sökmotoroptimering. Google presenterar riktlinjer som man bör förhålla sig till för att förbättra sitt resultat i sökningar som genomförs.

2. Skriv högkvalitativt innehåll

Det allra viktigaste när du väl skriver något i din hemsida, är att innehållet är fräscht, relevant och håller en hög nivå. Du bör ha frågan ”är detta något jag själv vill läsa, om jag inte kände till innehållet”? Mitt tips är att ha någon som kan dubbelkolla innehållet, om denne finner innehållet intressant.

3. Förstå dina konkurrenter

Du kanske upplever att dina konkurrenter har bättre tur vad gäller synlighet i sökmotorer? Jag tycker att det är väldigt viktigt att kontrollera och se hur konkurrenterna förhåller sig till den egna sajten. Det är först då som man faktiskt kan förstå hur man kan förbättra sin egna sökmotoroptimering.

4. Mobilanpassa webbsidan!

De senaste åren har Google straffat hemsidor som inte är mobilanpassade. På sistone har de även gått åt hårdare i detta hänseende, och försämrat sökresultaten för de sajter som inte är mobilanpassade. Google tillhandahåller även ett test som man kan genomföra på sin sajt, för att undersöka hur enkelt det är att använda sidan med en mobil enhet.

5. Aktivera HTTPS

Bild där ett grönt lås visas vänster om texten "https://qvi.st".

För att förbättra placeringen bör sidan även erbjudas via en krypterad kanal. Man kan enklast se att det är en krypterad kanal om det finns ett hänglås i adressfältet och när adressen börjar med https://.

Ovan nämnda tips gäller i skrivande stund, men besöker du sidan i framtiden är möjligheten stor att det tillkommit mer i bästa praxis. Punkterna 1 – 3 kommer förmodligen alltid att vara aktuella, även om det är svårt att sia om framtiden.

Skapa användare med PowerShell

PowerShell är ett kraftfullt verktyg i Windowsmiljön. Med detta skriptspråk kan man göra mycket administrativt arbete, bland annat skapande av användare vilket detta inlägg kommer att gå igenom. Lösningen som kommer att visas här kanske inte passar alla, däremot skall den skapa unika användare i domänen och även skapa ett engångslösenord. Lösenordet sparas med användarinformationen i den aktuella administratörens dokument-mapp. Jag publicerar skriptet här med förhoppningen om att den skall vara intressant och ge en fingervisning i hur man kan skapa användare för de som behöver det.

Alla användare skapas så att deras användarnamn består av de två första tecknen i för- och efternamnet. Heter man Sven Svensson blir alltså användarnamnet svsv. Skulle flera användare få ett likadant användarnamn adderas ett nummer till slutet, så om två Sven Svensson finns blir en svsv och den andra svsv2, på samma sätt adderas en siffra om fler personer skulle heta likadant. Då protokollet LDAP – vilket Active Directory använder sig av – kräver en unik identifierare (Distinguished Name) kan detta skript generera 26 + 1 sådana.

För att skriptet skall fungera bör följande saker finnas;

  • Windows Server med Active Directory
  • En csv-fil innehållande användare

Csv-filen skall innehålla följande:

  • Förnamn
  • Efternamn
  • Stad i vilken användaren finns
  • Avdelning i vilken användaren jobbar

Sedan är det valfritt att ha roll som attribut för användaren. För att exemplifiera csv-filen med två användare, kan det se ut på följande sätt:

Firstname;Lastname;Department;City;Role
Sven;Svensson;IT;Göteborg;Manager
Rut;Johansson;HR;Göteborg

Vad gäller skriptet och csv-filen måste dessa sparas i utf-8 format för att åäö skall visas korrekt. I normala fall sparar program såsom exempelvis Notepad filer i ASCII, som inte innehåller vissa svenska tecken. Istället visas ett tecken som kan liknas vid en romb med ett frågetecken inuti.

Skriptet kommer att spara en användare i example.com/Example/Stad/Avdelning/. Här kan förstås ordet Example bytas ut till namnet på den organisation det gäller.

############## METADATA ############## 
# AUTHOR: KRISTOFFER QVIST
# LICENCE: Apache Licence, v.2
# GOALS:
# * Check that new users actually are
#   unique within domain,
# * Assign unique email-addresses
# * Check for duplicate names within
#   an OU to correct these.
#####################################
 
param([string]$csvfile= [Environment]::GetFolderPath('MyDocuments') + "\thisFile.csv")
 
Import-Module ActiveDirectory
 
while((Test-Path -Path $csvfile) -eq $false) {
    $csvfile = Read-Host "Please, fill in the correct path to the .csv file"
}
 
$users  = Import-Csv -Delimiter ";" -Path $csvfile
 
foreach ($user in $users) {
    $fname      = $user.Firstname
    $fname      = $fname.Trim()
    $sname      = $user.Lastname
    $sname      = $sname.Trim()
    $dplName    = $fname+" "+$sname
    $domain     = "@example.com"
    # Get first two letters of firstname
    $samf       = $fname.substring(0,2)
    # Get first two letters of lastname
    $saml       = $sname.substring(0,2)
    $sam        = $samf+$saml
    $sam        = $sam.ToLower()
    $department = $user.Department
    $city       = $user.City
    $role       = $user.Role
 
    # The user should be added here
    $OU = "OU=$department,OU=$city,OU=Example,DC=example,DC=com"
    $dn = "CN=" + $dplName + "," + $OU
 
    # Place to store groups in
    $GroupOU = "OU=Groups,DC=example,DC=com"
 
    # Check if the OU exists, otherwise create it
    $LDAPOU = "LDAP://" + $OU
    $OUexists = [adsi]::Exists($LDAPOU)
 
    if ($OUexists -eq $false) {
        dsadd ou $OU
    }
 
    # Generate random password 8-byte password
    $length   = 2 # length x 4 equals the password length 
    $password = ""
    $chars    = "ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrtuvxyz".ToCharArray()
    for($i=0; $i -lt $length; $i++) {
        $password += $chars | Get-Random
    }
 
    $chars2 = "0123456789!#%/()".ToCharArray()
    for($i=0; $i -lt $length; $i++) {
        $password += $chars2 | Get-Random
    }
 
    for($i=0; $i -lt $length; $i++) {
        $password += $chars | Get-Random
    }
 
    for($i=0; $i -lt $length; $i++) {
        $password += $chars2 | Get-Random
    }
 
    # Create a clean email address (e.g. from Åsa.Lindén to asa.linden)
    $eaddress    = $fname.ToLower() + "." + $sname.ToLower()
    $eaddress    = $eaddress -replace "é","e"
    $eaddress    = $eaddress -replace "å","a"
    $eaddress    = $eaddress -replace "ä","a"
    $eaddress    = $eaddress -replace "ö","o"
 
    $email = $eaddress + $domain
 
    $emailExists = Get-ADUser -Filter { EmailAddress -like $email }
    $emailBase   = $eaddress
    $i = 2
 
    while ($emailExists -ne $null) {
        $email = $emailBase + "." + $i + $domain
        $emailExists = Get-ADUser -Filter {EmailAddress -like $email }
        $i++
    }
 
    # Create clean login name
    $sam    = $sam -replace "é","e"
    $sam    = $sam -replace "å","a"
    $sam    = $sam -replace "ä","a"
    $sam    = $sam -replace "ö","o"
 
    # Check if the user sam exists in AD already
    $checkADUser = Get-ADUser -LDAPFilter "(SamAccountName=$sam)"
    $i = 2
    $baseSam = $sam
 
    # If user exist, add a number to the end
    while ($checkADUser -ne $null) {
        $sam = $baseSam+$i
        $checkADUser = Get-ADUser -LDAPFilter "(SamAccountName=$sam)"
        $i++
    }
 
    # Check that the user has a unique DN
    $DNExists = Get-ADUser -Filter {distinguishedName -eq $dn }
    $i = 0
    $letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray()
    while ($DNExists -ne $null) {
        $dplName = $fname + " " + $letters[$i] + " " + $sname
        $dn = "CN=" + $dplName + "," + $OU
        #Write-Host $dn
        $DNExists = Get-ADUser -Filter {distinguishedName -eq $dn }
        $i++
    }
 
    # And use it in user principal name
    $upn        = $sam+$domain
 
    # Check if the localisation group exists, otherwise create it
    try {
        Get-ADGroup -Identity $city | out-null
    } catch {
        New-ADGroup -Name $city -GroupScope Global -Path $GroupOU
        Write-Host "New group '$city' created"
    }
 
    # Check if the shadow group exists, otherwise create it
    $ADShadowGroup = "SG_" + $department
    try { 
        Get-ADGroup -Identity $ADShadowGroup | out-null
    } catch {
        New-ADGroup -Name $ADShadowGroup -GroupScope Global -Path $GroupOU
        Write-Host "New group '$ADShadowGroup' created"
    }
 
    # This file will hold the user login credentials
    $file = [Environment]::GetFolderPath('MyDocuments') + "\" + $sam + ".txt"
 
    # Add the user to AD
    New-ADUser -SamAccountName $sam -Name $dplName -GivenName $fname -Surname $sname -DisplayName $dplName -UserPrincipalName $upn -Department $department -City $city -EmailAddress $email -AccountPassword (ConvertTo-SecureString $password -AsPlainText -Force) -AccountExpirationDate $null -ChangePasswordAtLogon $true -Enabled $true -Path $OU -ErrorAction SilentlyContinue
 
    # Add the role as title
    if ( $role -eq $false) {
        $role = $role.Trim()
        if ($role -ne $null) {
            Set-ADUser -Identity $sam -Title $role -ErrorAction SilentlyContinue
        }
    }
 
    # Add the user to an their repective shadow and localisation group
    Add-ADGroupMember $ADShadowGroup $sam
    Add-ADGroupMember $city $sam
 
    # Create file
    New-Item $file -type file -force -value "Login credentials for $dplName
    Domain: $domain
    Login name: $sam
    One time password: $password" | out-null
}
 
Remove-Module ActiveDirectory

Relaterat: Skapa användare med Perl.

Snabbare hemsidor med PHP7

I och med att PHP har lanserat version 7 kommer webben snart att upplevas snabbare. Enligt Zend kommer webben att upplevas upptill 50% snabbare än vad den är idag, på sidor som använder sig utav PHP med deras Zend-motor. Även PHP.net har skrivit om detta. Det är förstås alltid välkommet med ny mjukvara som ser till att hemsidor laddar snabbare (något som är extra bra för min blogg). Digital Ocean har ett intressant inlägg angående nyheterna i PHP7, som även innefattar lite siffror kring hur det mäter sig när de jämförde olika installationer med WordPress.

Men… vad hände med PHP6?
Bra fråga. Kort sagt kan man säga att det blev pannkaka av det hela: PHP6 påbörjades redan 2010, men problemen hopade sig när man försökte åtgärda alla fel i PHP5-grenen, enligt Sitepoint. Phil Sturgeon skrev att alla särdrag porterades tillbaka från PHP6 till PHP5.3-grenen, varför man kunde se en del nya funktioner när PHP5.3 presenterades.

Skapa användare med Perl

Uppdaterat: 2014.09.29

För ett tag sedan var jag tvungen att använda mig utav Perl för att generera användare och sedan ge dem ett tillfälligt lösenord som de kommer att få byta när de har loggat i. Systemet där skriptet användes är ett Linux-system (CentOS 6.5).

Skriptet matchar följande krav:

  • Ha stöd för utf-8
  • Läsa in för- och efternamn från en textfil
  • Skapa unika användare från textfilen
  • Skriva ut användarinformation till en ny textfil per användare, i en särskild mapp

För att kunna köra skriptet krävs modulen Text::Iconv, vilket kan testas genom att skriva perl -e 'use Text::Iconv;' i kommandotolken. Om du inte får ett svar, är modulen installerad. Om du får många felmeddelanden som svar, är modulen inte installerad. Hur man installerar moduler kan jag skriva om i ett annat inlägg, annars kan ni använda det ”gamla” sättet (vad gäller mitt skript) där icke-ASCII-tecken blir bytta till ett x. Eventuellt kan du kika på denna hemsida som förklarar hur man installerar ett verktyg som kan vara till stor hjälp i en CentOS-maskin, på engelska. Vidare står här hur man sedan använder verktyget för att installera modulerna.

Om du undrar över något, går det att skicka in ett mail till mig, så ska jag försöka svara så fort jag kan. Eventuellt, om det är flera som frågar, kan jag publicera svaren här i detta inlägg eller någon annanstans på hemsidan. Dock kommer skriptet inte att kontrollera om användaren lägger till mer input än vad som behövs.

För att få denna kod att vara såpass internationell som möjligt, används engelska kommentarer och variabelnamn.

#!/bin/usr/perl
#############METADATA############
# Author:	Kristoffer Qvist
# Version:	2
# Last
# Modified:	Sep 29th, 2014
# History:	Made utf-8 to
# 		ASCII converting
#		better.
#################################
use warnings;
use strict;
use Text::Iconv;
binmode STDOUT, 'utf8';
# Get file that contains users
my ($file, $userDir) = @ARGV;
while(not -e $file) {
print("Please, add a valid file containing your users.\n");
chomp($file = <STDIN>);
}
while(not -e $userDir) {
print("Please, add a valid folder to store the user password files\n");
chomp($userDir = <STDIN>);
}
# A basic check for script injection attempt
if($file =~ /;/ or $userDir =~ /;/) {
die("Script injection attempt found!\n");
}
# Put all new users in array
open(USERS, "<", $file) or die("The file $file could not be opened: $!");
chomp(my @new_users=<USERS>);
while (<USERS>) {
push (@new_users, $_);
}
close USERS or die($!);
# Get passwd content
my $passwd_file     = "/etc/passwd";
my $passwd_contents = open(PASSWD, "<", "/etc/passwd") or die("$!");
my @passwd;
while (<PASSWD>) {
push (@passwd, $_);
}
close PASSWD or die("$!");
# Set all existing users in hash
my %existing_users = ();
for(my $i=0;$i<scalar(@passwd);$i++) {
my @passwd_entry = split /:/,$passwd[$i];
$existing_users{$passwd_entry[0]} = $i;
}
# Add users to the system and create a random one-time password
foreach my $new_user(@new_users) {
my @names = split(/ /, $new_user); 
my $fn = substr($names[0],0,3);
my $ln = substr($names[1],0,2);
my $username = $fn.$ln;
# Converts non-ascii to x (old; latter converting is better)
# $username =~ s/[^[:ascii:]+]/x/g; 
# Encode usernames to ascii (new)
my $convert_this = Text::Iconv->new("UTF-8", "ASCII//TRANSLIT");
$username = $convert_this->convert($username);
$username = lc($username);
# Check for duplicate users, if found add number 
my $i = 1;
while(exists $existing_users{$username}) {
$username =~ s/[0-9]//g;
$username = $username.$i++;
}
$existing_users{$username} = $i;
my $password = join'', map +(0..9,'a'..'z','A'..'Z','!?()""')[rand(10+26*2)], 1..8;
`useradd $username -c "$new_user" &> /dev/null`;
`echo -e "$password\n$password" | passwd $username &> /dev/null`;
`chage -d 0 $username`;
open (USERFILE, ">", "$userDir/$username.txt") or die("The file $userDir/$username.txt could not be opened: $!\n");
print USERFILE "$new_user\n--------------------\n$username: $password";
close USERFILE or die("The file $userDir/$username.txt could not be closed: $!\n");
}
print("\nBatch completed!\n");

Kontrollera medlemskap av Shadow Groups

Uppdaterat 2015.02.26

Shadow groups används i Active Directory (AD) för att enklare administrera olika konton som är; satta i olika s.k. Organizational Units, OU:n. Ibland flyttar man användare över OU:n, av olika orsaker, och detta skript gör det enkelt att kontrollera att varje användare tillhör rätt grupp och OU. För automatisk kontroll bör detta skript schemaläggas.

  • PowerShell är installerat
  • Alla grupper har SG_ som prefix

I skriptet finns alla grupper i example.com/Accounts/Groups/Roles, medan användarna finns i deras respektive OU i example.com/Accounts.

Modifiering av skriptet
Då skriptet är licenserat i enlighet med Apache-licensen version 2 (se länk till höger av sidan) kan du göra i princip allt du vill med det. För att ändra katalogen där grupperna existerar ska variabeln $groups modifieras vid flaggan -SearchBase, och $base till platsen där alla OU:n med deras konton existerar.

Om du undrar något över detta skript och/eller vill ha hjälp med det kan du skicka mig ett mail. Dock kan jag inte lova att jag kan svara på det direkt, och om jag finner det intressant att publicera på bloggen kan jag komma att göra det med tillhörande svar.

############ METADATA ############
# Author: Kristoffer Qvist
# Description: Control that
# correct users, in the
# corresponding OU are set to
# their correct shadow group.
##################################
Import-Module ActiveDirectory
$groups = Get-ADGroup -Filter{name -like "SG_*"} -SearchBase "OU=Roles,OU=Groups,OU=Accounts,DC=example,DC=com"
foreach ($group in $groups) {
try {
# This block adds users to their correct Shadow Groups
$groupSAM = $group.SamAccountName
$OU       = $groupSAM.Replace("SG_", "")
$base     = "OU=$OU,OU=Accounts,DC=example,DC=com"
$users    = Get-ADUser -Filter * -SearchBase $base -Properties DistinguishedName | Select -ExpandPropert DistinguishedName
foreach ($user in $users) {
Add-ADGroupMember -Identity $groupSAM -Members $user
}
# This block removes users from wrong Shadow Groups
$groupMember = get-adgroupmember -identity $groupSAM
foreach ($member in $groupMember) {
$dgn    = $member.distinguishedName
$thisOU = Get-ADUser -LDAPFilter "(samAccountType=805306368)" -SearchBase $base
if ($thisOU -match $dgn) {
# Nothing to be done ; $dgn should match $thisOU
} else {
Remove-ADGroupMember -Identity $groupSAM -Members $dgn -confirm:$false
}
} 
} catch {
"There was an error adding/removing an user to the correct OU or shadow group. ($group)"
}
}
# It's good practice to remove the module used
Remove-Module ActiveDirectory

Bash-skript för att förflytta filer

Själv har jag haft behov av att förflytta filer mellan olika mappar i min dator. Då kan det vara skönt att använda sig utav skript som automatiserar förflyttningen helt och hållet (särskilt om man enbart har CLI). Det är skrivet i vanligt shellspråk (bash) och består av enbart några rader kod.

#!/bin/sh
############ METADATA ############
# Author: Kristoffer Qvist
# Description: Moves file(s) to
# predestined destination.
##################################
destination="/path/to/destination"
for file in "$@"; do
mv "$file" "$destination/$file"
done

Filerna som skall förflyttas finns är argument som skrivs efter skriptnamnet; alltså skript.sh fil.a fil.b som gör att dessa (det vill säga fil.a och fil.b) förflyttas till vald destination, som har skrivits i variabeln ”destination”. Detta skript gör ingen felsökning, och jag tar inget ansvar för eventuella fel som kan inträffa (nej, inte heller förlust av tangentbord eller guldfiskar).

© 2024 qvi.st

Tema av Anders NorenUpp ↑