ShadowCopy w Windows 2008 x64#

Ostatnio podczas przenoszenia plików użytkowników natknąłem się na typowy problem w-files.

Otóż przenieśliśmy katalogi domowe użytkowników na nowy serwer w2k8 x64. Włączyliśmy shadow copies. Zdefiniowaliśmy kopiowanie backupowe dfs-r do centrali, w celu późniejszego zrzucania stanu na tasiemki. Serwer sobie spokojnie śmigał, i wszystko wydawało się takie idealne. Nawet użytkownicy nie wydawali się niezadowolenia.

Wszystko niestety zepsuł błąd skryptu, który uszkodził strukturę katalogów na macierzy w centrali. Jako że dfs-r działa prawie niezawodnie, szybko dało się odczuć braki katalogów w oddziale.

Ale przecież jest shadow copy, więc nie powinno być problemu. Tak więc postanowiliśmy wejść do shadow copy, i spróbować przywrócić foldery.

I tu pojawił się pierwszy problem - shadow copy udawał, że nie umie znaleźć plików w folderach - wyświetlał się komunikat o ścieżce nie do znalezienia. Hmmm... problem uprawnień. Wobec tego przelogowujemy się i próbujemy jeszcze raz.. znowu nic.

Niestety w oddziale nie było żadnego innego serwera, a tylko stacje klienckie z xp. Wobec tego logujemy się zdalnie na stacje,i próbujemy odzyskać pliki. Jest, udaje się, ale niestety uprawnienia do plików się nie przenoszą.

Próbujemy volrest z w2k3 resource tools, niestety bez skutecznie. Narzędzie nie może sie podpiąć do shadow copy z windows 2008 w2k8 x64.

... chwilka załamania i wizja ręcznego ustawiania uprawnień.... nagle pomysł.., przecież shadow copy sharuje folder udostępniony z tą samą nazwą tylko z przedrostkiem określającym datę... wobec tego wejdźmy do właściwości otworzonej kopi shadow copy i znajdźmy ścieżkę... o, jest.

To teraz tylko robocopy w trybie backup – robocopy /b /COPY:DATSO /s /e /r:1 /w:1 i juz. Tylko kilka godzi stresu dla administratorów, i tylko godzina szukania narzędzia do przeglądania shadow copy : )

Tuesday, September 02, 2008 11:30:23 AM (Central European Standard Time, UTC+01:00) #    Comments [0]  |  Trackback

 

Autoryzacja użytkownika w C##

Czasami potrzebujemy fragmentu kodu, który umożliwi autoryzację użytkownika, który ma zablokowane konto - np. wtedy, kiedy loguje się do portalu typu self-service i chciałby sprawdzić, dlaczego ma zablokowane konto.

Przy próbie bindowania do AD extended error widzi rozróżnienie między kontem z zalokowanym, zablokowanym i złym hasłem. Niestety, tego błędu nie zobaczymy, jeśli użyjemy klas DirectoryServices czy ADSI - oba te interfejsy próbują się bindować dopiero przy podłączeniu do określonego obiektu i wyrzucają błąd PermissionDenied. Można oczywiście użyć klas novella do obslugi AD, ale niestety pod Windowsem nie wspierają TLS-a przy dostepie do LDAP-a.
Można tez użyc interopa i dllki advapi32.dll, co jest pokazane poniżej:

using System.Runtime.InteropServices;
(..)// w klasie
[DllImport("advapi32.dll", CharSet = CharSet.Auto,SetLastError=true)]
public static extern bool LogonUser(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);

public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
public const int LOGON32_LOGON_NETWORK = 3;
(..) // i w kodzie
IntPtr token = IntPtr.Zero;
bool res = LogonUser(
textBoxUserName.Text,
textBoxDomainName.Text,
textBoxPassword.Text,
LOGON32_LOGON_NETWORK,
LOGON32_PROVIDER_DEFAULT,
ref token);
label1.Text= Marshal.GetLastWin32Error().ToString()+" : "+res.ToString();

Marshal.GetLastWin32Error() powinien nam zwrócić różne kody błędu przy różnych próbach dostępu do AD.

Tuesday, May 15, 2007 4:14:33 PM (Central European Standard Time, UTC+01:00) #    Comments [0]  |  Trackback

 

Poprawianie polskich znaków w DisplayName#

Mieliśmy ostatnio problem z polskimi znakami w displayname - dostaliśmy listę kont do załozenia która była w innym kodowaniu niz zazwyczaj, i automat załozył konta z polskimi znakami w displayName. Niestety Linuxy przy zakladaniu aliasów pocztowych nie poradziły sobie z polskimi znakami, więc mieliśmy ok 100 kont do dodania.

Kfaz po długiej i cięzkiej nauce powershella napisał taki skrypt:

$Root = New-Object DirectoryServices.DirectoryEntry $strROOT
$logname = "Nazwiska";
$logname += get-date -format "yyyyMMdd_hhmmss";
$logname +=".log";

$Searcher = New-Object DirectoryServices.DirectorySearcher
$Searcher.SearchRoot = $root
$searcher.Filter =  "(&(objectClass=User)(!(objectClass=Computer)))";
$users = $searcher.findAll();
$l=0;
$log=@();
$polish = "ą","ć","ę","ł","ń","ó","ś","ź","ż","Ą","Ć","Ę","Ł","Ń","Ó","Ś","Ź","Ż";
$latin = "a","c","e","l","n","o","s","z","z","A","C","E","L","N","O","S","Z","Z"

foreach ($user in $users)
{
 write-host "." -NoNewLine;

 if (([string] $user.properties.displayname) -match "[ąćęłńóśźżĄĆĘŁŃÓŚŹŻ]")
  {
   $de = New-Object DirectoryServices.DirectoryEntry $user.Path;
   $temp = $de.displayName;
   for ($i = 0; $i –lt $polish.count; $i++)
   {
    $temp = ([String]$temp).Replace($polish[$i], $latin[$i]);
   }

   $log+=$de.SAMAccountName +" "+$de.displayName+" "+$temp;
   $de.SAMAccountName;
   $de.displayName;
   $temp;
   echo "-------------------------------------";

   $de.displayName = $temp;
   $de.CommitChanges();
   $l++;
  }
}

echo "Przetworzonych  " $l | out-file $logname -Append
$log | out-file $logname -Append

echo "Przetworzonych  " $l

Thursday, January 04, 2007 12:40:47 PM (Central European Standard Time, UTC+01:00) #    Comments [0]  |  Trackback

 

Poprawianie DisplayName#

Po przejrzeniu kilku rekordów userów okazało się, że niektórzy mają w Display Name poustawiane pomiędzy imieniem i nazwiskiem 2 spacje zamiast 1. Aby to skorygować, powstał ten skrypt:

$data=get-date -format g
$comment="[changedDN "+$data+"by PeKi]"
$logname = "changedDN";
$logname += get-date -format "yyyyMMdd_hhmmss";
$logname +=".log";
$l=0
$Root = New-Object DirectoryServices.DirectoryEntry $strROOT
Searcher = New-Object DirectoryServices.DirectorySearcher
$Searcher.SearchRoot = $root
$searcher.Filter = "(&(objectClass=person)(objectcategory=person)(displayName=* *))";
$users = $searcher.findAll();
$log=@();
foreach ($user in $users)
{
    $de = New-Object DirectoryServices.DirectoryEntry $user.Path;
    $log+=$de.SAMAccountName + " " + $de.displayName
    $de.displayName=([String]$de.displayName).Replace(" "," ")
    $l++
}

echo "Przetworzonych " $l | out-file $logname -Append
$log| out-file $logname -Append

echo "Przetworzonych " $l
$log

A ten skrypt poprawia błąd, w którym nazwisko jest powtórzone 2 razy:

$data=get-date -format g
$comment="[changedDN "+$data+"by PeKi]"
$logname = "changedDNGN";
$logname += get-date -format "yyyyMMdd_hhmmss";
$logname +=".log";

$Root = New-Object DirectoryServices.DirectoryEntry $strROOT
Searcher = New-Object DirectoryServices.DirectorySearcher
$Searcher.SearchRoot = $root
$searcher.Filter = "(&(objectClass=person)(objectcategory=person)(displayname=* * *)(givenName=* *)(sn=*))";
$users = $searcher.findAll();
$log=@();
$l=0
foreach ($user in $users)
{
    $de = New-Object DirectoryServices.DirectoryEntry $user.Path;
    $gns=([String]$de.givenName).Split(' ')[1].tolower()
    $sn=([String]$de.sn).tolower()
    if ($gns.CompareTo($sn) -eq 0)
    {
    $newGN=([String]$de.givenName).Split(' ')[0];
    $newDN=$newGN+" "+([String]$de.sn)
    $log+=$de.SAMAccountName+ $de.givenName + $de.displayName + $newGN +$newDN
    write-host $l
    $de.givenName=$newGN
    $de.displayName=$newDN
    $l++
    }    
}

echo "Przetworzonych " $l | out-file $logname -Append
$log| out-file $logname -Append

echo "Przetworzonych " $l
$log

Thursday, October 26, 2006 1:30:43 PM (Central European Standard Time, UTC+01:00) #    Comments [0]  |  Trackback

 

Logowanie do AD z Grupami#

Po małym przeszukaniu internetu (głównieCodeProject i ExpertExchange) udało mi się w końcu zrobić logowanie do AD z wykorzystaniem grup (ale tylko tych jawnie wpisanych użytkowników, bez rozwijania grup zagnieżdżonych).

Główny kod programu:

//try autchenitcation
string[] groupsToCheck ={ "cwiczeniowcy", "Asystenci", "operatorzy", "wykladowcy" };

try
{
 //bind to ad
 DirectoryEntry de = new DirectoryEntry("LDAP://dc=pjwstk,dc=edu,dc=pl", TBLogin.Text,  TBHaslo.Text);
 DirectorySearcher mySearcher = new DirectorySearcher(de);
 mySearcher.Filter = ("(&(ObjectCategory=Person)(ObjectClass=user)(SAMAccountName=" + TBLogin.Text  + "))");
 mySearcher.PropertiesToLoad.Add("givenName");
 mySearcher.PropertiesToLoad.Add("sn");
 mySearcher.PropertiesToLoad.Add("Path");
 mySearcher.PropertiesToLoad.Add("primaryGroupId");
 mySearcher.PropertiesToLoad.Add("objectSid");
 SearchResult results = mySearcher.FindOne();
 if (null != results)
 {
  uImie = results.Properties["givenName"][0].ToString();
  uNazwisko = results.Properties["sn"][0].ToString();
  //get user groups
  ArrayList groups = new ArrayList();
  DirectoryEntry obUser = new DirectoryEntry(results.Path);
  object obGroups = obUser.Invoke("Groups");
  foreach (object ob in (IEnumerable)obGroups)
   {
    DirectoryEntry obGpEntry = new DirectoryEntry(ob);
    groups.Add(obGpEntry.Name);
   }
  //get primary group
  int primaryGroupId = (int)results.Properties["PrimaryGroupID"][0];
  byte[] userSid = results.Properties["objectSid"][0] as byte[];
  byte[] primaryGroupSid = BuildPrimaryGroupSID(userSid, primaryGroupId);
  string adsPath = String.Format("LDAP://<SID={0}>", BuildOctetString(primaryGroupSid));
  DirectoryEntry objUser = new DirectoryEntry(adsPath, TBLogin.Text, TBHaslo.Text);
  groups.Add((string)objUser.Properties["name"].Value);
  //check if member is in group
  bool isInGroup =false;
  foreach (string stc in groupsToCheck)
   if (groups.Contains(stc)) isInGroup = true;
  if (isInGroup)
   {
    //Authenticated
   }
  else
  {
   LblError.Text = "Nie masz uprawnien do wypelnienienia ankiety";
  }
 }
  else LblError.Text += "Blad Autoryzacji";
 }
catch (Exception dsce)
{
 LblError.Text = "Blad Autoryzacji";
}
// insertXML(uImie,uNazwisko);

Do tego potrzebujemy jeszcze funkcję do konwersji SIDów

private byte[] BuildPrimaryGroupSID(byte[] userSid, int primaryGroupId)
{
 byte[] rid = BitConverter.GetBytes(primaryGroupId);
 for (int i = 0; i < rid.Length; i++)
 {
  userSid.SetValue(rid[i], new long[] { userSid.Length - (rid.Length - i) });
 }
 return userSid;
}

private string BuildOctetString(byte[] bytes)
{
 StringBuilder sb = new StringBuilder();
 for (int i = 0; i < bytes.Length; i++)
 {
  sb.AppendFormat("{0}", bytes[i].ToString("X2"));
 }
 return sb.ToString();
}

I klasę, która produkuje SID

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Runtime.InteropServices;
using PSID = System.IntPtr;
using HLOCAL = System.IntPtr;
using BOOL = System.Int32;
using HANDLE = System.IntPtr;
using DWORD = System.UInt32;

/// <summary>
/// Summary description for Class1
/// </summary>
public class sid
{
 [DllImport("Advapi32.dll", CallingConvention = CallingConvention.Winapi, SetLastError = true,  CharSet = CharSet.Auto)]
 public static extern BOOL ConvertSidToStringSid(PSID Sid, out IntPtr StringSid);

 public unsafe static string UnsafeGetSidString(object sid)
 {
 string sidString = null;
 IntPtr strPtr;
 fixed (byte* psid = (byte[])sid)
  {
   IntPtr psidPtr = (IntPtr)psid;
   BOOL rc = ConvertSidToStringSid(psidPtr, out strPtr);
   Win32.CheckCall(rc);
   try
   {
    sidString = Marshal.PtrToStringAuto(strPtr);
   }
   finally
   {
    Win32.LocalFree(strPtr);
   }
  }
  return sidString;
 }
}
public class Win32
{
 [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 public static extern HLOCAL LocalFree(HLOCAL hMem);
 public static void CheckCall(bool funcResult)
 {
  if (!funcResult)
  {
   ThrowLastError();
  }
  }
 public static void CheckCall(BOOL funcResult)
 {
  CheckCall(funcResult != 0);
 }
 public static void CheckCall(HANDLE funcResult)
 {
  CheckCall(!IsNullHandle(funcResult));
 }
 public static DWORD GetLastError()
 {
  return (DWORD)Marshal.GetLastWin32Error();
 }
 public static bool IsNullHandle(HANDLE ptr)
 {
  return (ptr == IntPtr.Zero);
 }
 public static void ThrowLastError()
 {
  Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
 }
}

 

Oczywiście w web.config w <system.web> musimy dodać obsługę funkcji typu unsafe:

        <compilation>
            <assemblies>
             <add assembly="System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
            </assemblies>
            <compilers>
                <compiler language="c#;cs;csharp" extension=".cs" compilerOptions="/unsafe" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
            </compilers>
        </compilation>

Tuesday, October 17, 2006 9:33:34 AM (Central European Standard Time, UTC+01:00) #    Comments [2]  |  Trackback

 

Jabber COM component#
 Ostatnio brakowało mi trochę komponentu do skryptu, który umożliwiałby wysyłanie powiadomień na jabbera.
    Na JabberStudio powstał projekt jabber-net zawierający biblioteki do C#, które umożliwiają napisanie własnego klienta jabbera. Stąd był już tylko krok do opakowania ich w interfejsy COM-owe, co umożliwiło ich wykorzystanie w skryptach.

 Biblioteczka dostępna tutaj.
Wednesday, July 19, 2006 1:16:42 PM (Central European Standard Time, UTC+01:00) #    Comments [0]  |  Trackback

 

Windows Server 2003 Service Pack 2#

Na connect.microsoft.com pojawiła się wersja pre-beta SP2 do w2k3. Warto się bliżej zapoznać z dwu powodów.

 Po pierwsze dochodzi znane z R2 MMC 3.0 - czasami snapiny nie działają, więc warto przetestować wcześniej.

  Po drugie i najważniejsze - dochodzi WDS, czyli następca RIS-a. A ja się zastanawiałem, co będę robić podczas wakacji...

RIS | Windows
Sunday, June 25, 2006 10:02:56 AM (Central European Standard Time, UTC+01:00) #    Comments [0]  |  Trackback

 

TDSSNIClient initialization failed with error 0x34 , status code 0x1d#

SQL Server 2005 po ostatnim biuletynie zabezpieczeń się zepsuł - tzn. nie wstawał. W logach był błąd taki jak w TOpicu. Po przejrzeniu paru blogów o podobnych błędach, np http://blogs.msdn.com/sql_protocols/archive/2006/01/10/511330.aspx , czy http://blogs.msdn.com/sql_protocols/archive/2006/04/28/585835.aspx?Ajax_CallBack=true mogłem dojść do przekonania, ze błędem jest zduplikowany adres IP.

Ale co zrobić jeśli nie jest? I do tego serwer nasłuchuję tylko na jednym adresie?. Metodą prób-i-błędów doszedłem do tego ze muszę włączyć nasłuchiwanie na wszystkich adresach - wtedy serwer się podnosi, ale komunikacji z zdalnego komputera dalej się nie da uzyskać.

Zeby wszystko zaczeło działać, musiałem jawnie określić port w sekcji IPALL dla wszystkich IPków.

Sunday, June 18, 2006 9:52:09 AM (Central European Standard Time, UTC+01:00) #    Comments [0]  |  Trackback

 

ISA2006#
    Pojawiła się już RC ISA2006 - do zessania ze stron Microsoftu.

Poza poprawieniem troszeczkę interfejsu, dodaniu paru kreatorów, nic się nie zmieniło. A co najważniejsze, mimo zapowiedzi na MTS, czy na SecuritySUmmit, nie wprowadzono obsługi IPv6. Przecież po to Microsoft wprowadzał ISA2006 (a  nie kolejnego SP), żeby współpracowała dobrze z Vistą i Longhornem. A podstawowym załeżeniem sieci w Viscie i Longhornie, jest umożliwienie działania każdej usługi na IPv6.
Według mnie, Microsoft nie uważa żeby wykorzytsanie IPv6 było popularne przed pojawieniem się Longhorn serwera (palnowane na jesień 07), i prawdopodobnie dopiero w ISA2007(prawdopodobnie listopad 07) pojawi się ipv6.

IPv6 w ISA wg. mnie umożliwiło by szybsze przejście użytkowników na ten protokół, w szczególności, dzięki funkcją publikacji serwerów, nie musielibyśmy wystawiać serwerów po IPv6 na zewnątrz. Wystarczyło by odpowiednio skonfigurować isę.

Wednesday, June 14, 2006 4:27:52 PM (Central European Standard Time, UTC+01:00) #    Comments [0]  |  Trackback

 

Najfajniejsze pytanie w Helpie Longhorn servera Beta 2#

Can I still use IPv4 addresses with this version of Windows?

Yes, you can.

To w skrócie podsumowuję zmiany w Longhorn Serwerze. W końcuy została dodana pelna obsługa protokołu IPv6 (tzn. AD i RPC po IPv6, praca w domenie tylko po IPv6 [na razie testowałem tylko z visą], pełny Firewall i IPSEC z obsługą IPv6 i konfigurowaniem graficznym przez GPO[w odroznieniu od XP, gdzie IPv6FW był, ale jego konfiguracja była strasznie trudna], DNS z obsługą REV IPv6 i automatycznym tworzeniem pointerów[jak w IPv4], DHCPv6.

Saturday, June 10, 2006 7:53:24 AM (Central European Standard Time, UTC+01:00) #    Comments [0]  |  Trackback

 

Migracja do R2#

R2 ujrzało juz światło dzienne - wiec pora na migrację. Zgodnie z podręcznikami, abyśmy mogli korzystać z bardziej zaawansowanych opcji typu zarządzanie drukarkami, czy nowym frs'em, musimy zupdatować schema. W większości przypadków wystarczy po prostu uruchomić adprep /forestprep z drugiego CD. Jednak jeśli wcześniej mieliśmy zainstalowany SFU < 3.0, pojawiaja się problemy.

Problemy wynikaja głównie z tego, ze wersje < 3.0 uzywały schematu kompatybilnego z possixem, a schemat z 3.0 i wyzszych uzywa atrybutów i klas z przedrostkiem msf30. Wynikało to z tego ze w czasach gdy wchodziło 3.0 królującym OSem był W2k serwer, który uniemozliwiał zmienianie nazw czy ustawianie flagi defunct na atrybutach. Schematy te się rózniły i to w dość znacznym stopniu, więc aby uniknąć problemów z migracją Microsoft wprowadził nowy schemat nazewniczy.

W Services for Unix mamy powrót znowu do schematu possixowego - takiego jak w SFU 2.0. Czyli przy migracji dostaniemy błędy mówiące ze dane atrybuty juz istnieją. Ni9estety nie ukazał się jeszcze zadny kb opisujący co zrobić.

Metoda jest bardzo prosta. Po pierwsze sprawdzamy czy gdziekolwiek jeszcze uzywamy atrybutów z SFU 2.0 . jeśli nie, a w większości przypadków nie będziemy uzywali, jako ze zrobiliśmy migrację do 3.0, mozemy przejść dalej. Jeśli jednak uzywamy atrybutów z 2.0 musimy zrobić pelen ich backup.

Drugim krokiem jest, korzystając z Active directory Schema ,przestawienie wszystkich spornych atrybutów i klas w tryb defunct - oczywiście do tego potrzebujemy zeby domena i las były w trybie windows 2003 native. Większość atrybutów jest powiązana z klasami, w tym przypadku musimy usunąć wszystkie zalezności z klas.

Kolejnym krokiem jest zmiana nazwy atrybutów które przestawiliśmy w tryb defunct. Niestety ta wersja adprepa nie ma mozliwości wykorzytsania starych atrybutów.

I ostatni krok - adprep /forestprep - i powinno wszystko działać.

Saturday, April 29, 2006 12:48:54 PM (Central European Standard Time, UTC+01:00) #    Comments [0]  |  Trackback

 

VS2k5 Unattended#
W sumie instalacja nienadzorowana jest całkiem dobrze opisana. A więc mamy dwa tryby takiej instalacji:

a) Response File

Odpalamy setup za pomocą Setup/setup.exe /CreateUnattend="c:\unattned.inf" I torzymy plik z odpowiedzią. Cały proces jest prosty i przyjemny, posiada tylko pare drobnych wad.
Po pierwsze, instaluję całe VS łącznie ze wszystkimi wymaganymi bibliotekami, nawet jeśli biblioteki są juz zainstalowane. Co w przypadku .Net Frameworka zabiera juz ok.10min, a cały proces instalacji wydluza o ok.20.
Po drugie, nie nadaję się do upgradów. Przy zainstalowanym wcześniej VS np. przez instalacje SQL Servera 2k5, instalator stwierdzi ze VS jest juz zainstalowane i pominie ten krok.

b) Transform

Odpalamy setup za pomocą Setup/setup.exe /CreateUnattend="c:\unattned.inf" . I tu wielka, gigantyczna uwaga: pliki setupu(a dokładniej .msi) nie mogą być read-only!! Trzeba usunąć atrybut tylko-do-odczytu, bo inaczej instalacja zawodzi.
Jak na razie nie testowałem jeszcze instalacji z wykorzystaniem transform, gdyz nie wiedziałem o powyrzszej uwadzę.

Oczywiście przy instalacji z transform musimy wcześniej doinstalować komponenty tj. MSXML, Dexplore, czy .Net framewok. Microsoft radzi uzywać instalek znajdujących się w katalogu wcu. W większości są to spakowane archiwa, które przy instalacji rozpakowują się na dysk lokalny i dopiero z niego są instalowane. Przy szybkiej sieci, gdy nie zalezy nam na wydajności łącza, mozemy je rozpakować i odpalić tylko same instalki. W normalnych warunkach zaoszczędza nam to ok. 10min.
Przykładowy plik cmd do instalki z rozpakowanych archiwów:

WindowsInstaller-KB893803-v2-x86.exe /passive /norestart

msxml6.msi /qr REBOOT=RS

dotnetfx\install.exe /qb

DExplore\install.exe /qb

jsredist\install.exe /qb

Thursday, March 02, 2006 11:00:27 PM (Central European Standard Time, UTC+01:00) #    Comments [0]  |  Trackback

 

Autologon i RunOnceEx#

Skrypty które automatycznie logują się na dany komputer i odpalają dany program moga stworzyć prosty system instalacji oprogramowania. Taki przykładowy skrypt to:

@ECHO OFF

REM Setting Autologon

REG ADD "\\%1\HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "DefaultDomainName" /t REG_SZ /d "PJWSTK" /f
REG ADD "\\%1\HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "DefaultUserName" /t REG_SZ /d "Admin_Name" /f
REG ADD "\\%1\HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "DefaultPassword" /t REG_SZ /d "Admin_Password" /f
REG ADD "\\%1\HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "AutoAdminLogon" /t REG_SZ /d 1 /f
REG ADD "\\%1\HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "AutoLogonCount" /t REG_SZ /d 1 /f
REG ADD "\\%1\HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "ForceAutoLogon" /t REG_SZ /d 1 /f
REG ADD "\\%1\HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "CachePrimaryDomain" /t REG_SZ /d "PJWSTK" /f
REG ADD "\\%1\HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "AltDefaultUserName" /t REG_SZ /d "pkrzysz" /f
REG ADD "\\%1\HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "AltDefaultDomainName" /t REG_SZ /d "PJWSTK" /f
REG ADD "\\%1\HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "DontDisplayLastUserName" /t REG_SZ /d "0" /f
REG ADD "\\%1\HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\DomainCache" /v "PJWSTK" /t REG_SZ /d "pjwstk.edu.pl" /f

REM Setting Autostart

REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx" /t REG_SZ /v Title /d "Installing Additional Software" /f
REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx" /t REG_DWORD /v Flags /d 306 /f
REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\install01" /t REG_SZ /v "" /d "Preparing install" /f
rem REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\install01" /t REG_SZ /v 1 /d "rundll32.exe user32.dll, LockWorkStation " /f
REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\install01" /t REG_SZ /v 2 /d "fsutil quota modify c: 80000000000 80000000000 PJWSTK\pkrzysz" /f
REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\install01" /t REG_SZ /v 3 /d "fsutil quota modify c: 80000000000 80000000000 PJWSTK\risasi" /f
REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\install01" /t REG_SZ /v 4 /d "fsutil quota disable d:" /f

REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\install02" /t REG_SZ /v "" /d "Installing..." /f
REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\install02" /t REG_SZ /v 1 /d "echo ." /f

REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\install03" /t REG_SZ /v "" /d "Cleaning Registry..." /f
REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\install03" /t REG_SZ /v 1 /d "reg.exe add """HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon""" /v """DefaultDomainName""" /t REG_SZ /d """PJWSTK""" /f" /f
REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\install03" /t REG_SZ /v 2 /d "reg.exe add """HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon""" /v """AutoAdminLogon""" /t REG_SZ /d """0""" /f" /f
REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\install03" /t REG_SZ /v 3 /d "reg.exe add """HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon""" /v """AutoLogonCount""" /t REG_SZ /d """0""" /f" /f
REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\install03" /t REG_SZ /v 4 /d "REG.exe DELETE """HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon""" /v """DefaultUserName""" /f" /f
REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\install03" /t REG_SZ /v 5 /d "REG.exe DELETE """HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon""" /v """DefaultPassword""" /f" /f
REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\install03" /t REG_SZ /v 6 /d "REG.exe DELETE """HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon""" /v """ForceAutoLogon""" /f" /f
REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\install03" /t REG_SZ /v 7 /d "rEG.exe DELETE """HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon""" /v """DontDisplayLastUserName""" /f" /f
REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\install03" /t REG_SZ /v 8 /d "REG.exe DELETE """HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run""" /v """afterreboot""" /f" /f

REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\install04" /t REG_SZ /v "" /d "Rebooting..." /f
REG ADD "\\%1\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\install04" /t REG_SZ /v 1 /d "shutdown -r -t 0 -f" /f


shutdown -r -f -t 0 -m \\%1

Wednesday, March 01, 2006 1:53:18 PM (Central European Standard Time, UTC+01:00) #    Comments [0]  |  Trackback

 

Problem z instalacjami - rozwiązany#
 Był sobie taki problem:

Przy instalacji dowolnego programu korzystającego z MSI, przy etapie kopiowania plików, podczas kopiowania dll wyskakiwał błąd. W zaleznosci od interpretacji mówił on albo o braku miejsca na dysku, albo o braku uprawnień, albo po prostu o niemozliwosci zapisania pliku na dysk.

Problem był sam w sobie dziwny, poniewaz miejsce na dysku było, oraz uprawnienia były odpowiednie. Instalator otwierał plik, czyścił go, zapisywał, i koniec - plik miał 0 bajtów i wyświetlał się błąd.Po cofnięciu instalacji pliki były przywracane.

Oczywiście zabrałem się do problemu wyposazony w combo Regwatch,filewatch z sysinternals. Skanowanie rejestru nic nie dało, natomiast podczas skanowania plików okazało się ze zawodzi operacja SET SECURITY.

Zastanawiałem się więc czemu jako administrator systemu, a nawet jako uzytkownik Local System nie mogę zainstalować najprostszych programów. W ruch poszedł google, Platform SDK, kbAlertz!, msfn i wiele innych. I nic. Robocza hipoteza nr.1 -> system mi nie daję tokenu który umozliwia zmianę uprawnień dla danego pliku.

Szybko zobaczyłem Security, oraz ownera pliku. Zgodnie z moimi przypuszczeniami, właścicielem okazał się uzytkownik risasi.
Kto to jest risasi? Mój uzytkownik domenowy do instalacji unattended z RIS-a (RIS  Automated System Installer). Na początku jest on przyłączany do grupy Adminisratorów lokalnych, następnie są zdejmowane dla niego quoty. Po skończonej instalacji jest usuwany z Administratorów lokalnych, i quota jest przywrócona.

Jako ze właścicilem pliku jest risasi, to moze trzeba go dodać do administratorów zeby działało? Niestety nie.
To moźe po zmianie właściciela pliku będzie działało? Działało:)

Robocza hipoteza nr.2 -> Wyrzucenie uzytkownika z grupy Administratorów lokalnych bez zmiany właściciela dll które zainstalował nie jest dobrym pomysłem.

Po miesiącu powróciłem do tematu. Przeszłem jeszcze raz przez Filemona, regmona, logi z instalacji. Moją uwagę zwróciła wiadomosć rozszerzona przy polu SET SECCURITY -> disk full.
Okazało sie, ze uzytkownik risasi ma grubo przekroczoną quotę na dysku. Co ma quota do właściciela pliku?

Okazało sie ze msiexec tylko dla dll po nadpisaniu pliku zmienia ownera na ownera który był przed instalacją.

Niby mały błąd, a jednak moze duzo zepsuć. Ja nie mogłem np. instalować nowszych wersji programów, zarówno ręcznie jak i poprzez GPO.

Błąd ten moze być tez wykorzystany przez uzytkowników do ataku na miejsce na dysku komputera, gdyz quoty dla tych dll są naliczane dla ownera.

Wednesday, February 22, 2006 10:56:59 PM (Central European Standard Time, UTC+01:00) #    Comments [1]  |  Trackback

 

Microsoft AntiVirus#
 W końcu Microsoft zamierza wypuścić antyviruas. Oczywiscie nie dla użytkowników końcowych, dla których jest OneCare( antyvirus,antysoywar,firewall), a dla klientów korporacyjnych - i targetowany zarówno dla stacji klienckich i serwerów, jak i jako serwer filtrujący

http://www.microsoft.com/windowsserversystem/solutions/security/clientprotection/default.mspx

Nie pozostaje zatem nic innego jak poczekać do magicznego Q4 2006 jak będzie dostępny na MSDNie

Friday, February 10, 2006 1:27:40 AM (Central European Standard Time, UTC+01:00) #    Comments [0]  |  Trackback

 

VMvare Server za Free#

VMWare wypuścił serwer za free dla Windowsów i Li nuksów!
Jest to prawdopodobnie odpowiedź na Microsoftowy Virtual Server R2, który kosztuję 99$; czy darmową Linuxową platformę wirtualizcyjną XEN.
Oczywiście produkt ten plaasuję się w podobnie jak VSR2 w kategori GSX, czyli systemu serverowemu instalujacemu się na bazie istniejącego systemu; a nie tak jak w ESX czy XENie jako dedykowany server.
Poniżej link a mnie pozostaje czekać aż XEN dogoni ESX z VirtualCenter pod względem funkcjonalności
http://www.vmware.com/products/server/

Tuesday, February 07, 2006 10:08:24 PM (Central European Standard Time, UTC+01:00) #    Comments [2]  |  Trackback

 

Opera 9.0 TP2#

Po przetestowaniu IE 7.0 beta 2 byłem pełen nadzieji w stosunku do Opery. Może w końcu będzie działała autentykacja NTLMowa oraz AJAX? Niestety, specjaliści od opery skupili się na gadżetach, a nie na pisaniu porządnego kodu (zgodnie z powiedzeniem Billa zprzed 10 lat- jeśli nie mozesz czegoś zrobić dobrze, zrób zeby to ładnie wyglądało).


I tak dla NTLMa jest dodany experymentalny support, który jednak nie działa dla żednego site'a którego testowałem, a AJAXa po prostu nie ma! Jak można przegapić najciekawszą techologię Webową od czasu flasha!? Przecież wszyscy nad tym aktywnie pracują - czy to ruch Open Source z AJAXem, czy to Microsoft z ATLASem i XMLHTML. Jak tak dalej pójdzie to Opera stanie się tak niszową przeglądarką jak Netscape.


Co więc się zmieniło? Poza wsparciem dla CSS 3.0 i poprawieniem parsowania HTMLa programiści opery skupili się głównie na takich rzeczach jak obsługa torrentów,wbudowany edytor wyszukiwarek,nowe strony about:xxx i tym podobne szczególiki. Czym więc ta wersja Opery zasłużyła sobie na nowy numerek edycji? Według mnie obsługą widgetsów - czyli małych pluginów mogących wyświetlać dodatkowe okienka tj. zegarek czy stan konta pocztowego. Ciekawe jak długo minie aż w operze będą się automatcznie wyświetlały reklamy, czy powstawały strony z reklamami popupwidget.

Tuesday, February 07, 2006 10:02:57 PM (Central European Standard Time, UTC+01:00) #    Comments [0]  |  Trackback

 

Wysylanie meijli ze skryptow, czyli CDO.Message#

Najprostszy skrypt do wysyłania meili w vbsie wyglada następująco:

Set objMessage = CreateObject("CDO.Message")
objMessage.Subject = "Example CDO Message"
objMessage.From = "me@my.com"
objMessage.To = "test@paulsadowski.com"
objMessage.TextBody = "This is some sample message text."
objMessage.Send

Oczywiście mozemy dodadć załącznik, czy wysłać wiadomość w htmlu

'The line below shows how to send using HTML included directly in your script
objMessage.HTMLBody = "<h1>This is some sample message html.</h1>"

'The line below shows how to send a webpage from a remote site
objMessage.CreateMHTMLBody "http://www.paulsadowski.com/wsh/"

'The line below shows how to send a webpage from a file on your machine
objMessage.CreateMHTMLBody "file://c|/temp/test.htm"

objMessage.Bcc = "you@your.com"
objMessage.Cc = you2@your.com


Bardziej rozbudowana postać do wysyłania przez serwer z autentykacją ntlm:

Const cdoSendUsingPickup = 1 'Send message using the local SMTP service pickup directory.
Const cdoSendUsingPort = 2 'Send the message using the network (SMTP over the network).

Const cdoAnonymous = 0 'Do not authenticate
Const cdoBasic