Archive

Archive for the ‘Jezyki programowania’ Category

Pobieranie nazwy hosta z dhcp.

August 26th, 2009 6 comments

Jakiś tydzień temu zabrałem się za kończenie nowych obrazów dla komputerów na salach laboratoryjnych. Poza drobnymi zmianami (dystrybucja lekkich aplikacji via SCCM) chciałem zminimalizować czas jaki poświęcałem na zmianę nazw komputerów po klonowaniu. Kilka lat temu przyjęliśmy, że komputery na salach będą się nazywać KompXXX-YY. Gdzie XXX to numer sali a YY to komputer na miejscu YY licząc od prawej strony sali. W systemach Linux rozwiązanie było proste :) Dorzuciliśmy opcję 12 do DHCP i systemy pobierały sobie odpowiednią nazwę z serwera DHCP. W przypadku Windows sprawa się komplikuje i dobrze by było nazwy zmienić na samym początku by nie robić sobie bałaganu. Nazwę można pobrać czy wygenerować na kilka sposobów:

  • pobranie nazwy z DNS – wszystko fajnie, tylko jak nazwy nie mam w DNS bo pojawi się po dodaniu Windowsa do domeny
  • wykorzystanie Sysprepa do generowania nazwy Komp400-XX – Muszę mieć kilka plików unattend do Sysprepa :/
  • przeparsowanie otrzymanego Adresu IP i wygenerowanie nazwy komputera.  – Czasem od naszej reguły nazewnictwa zdarzają się wyjątki:)
  • pobranie nazwy z DHCP – idealne rozwiązanie.

 

Skoro miałem wszystkie nazwy w DHCP to teraz wystarczyło pobrać odpowiednią opcje i zamienić nazwę stanowiska:) Jak sie okazało otrzymanie nazwy komputera z DHCP i wrzucenie jej do jakieś zmiennej nie jest takie proste. Jedyne dostępne API dla Windowsowego klienta DHCP jest napisane w C++:/  Opcje z DHCP pobieramy za pomocą funkcji DHCPRequestParams, która przyjmuje na wejściu kilka parametrów. Między innymi wymagane jest podanie nazwy interfejsu sieciowego. TUTAJ UWAGA nazwa interfejsu jest rozumiana jako identyfikator urządzenia a nie jako np. “Połączenie lokalne”. Identyfikator również możemy sobie wyciągnąć za pomocą API do interfejsów sieciowych.  Przyznam się, że stworzenie działającej aplikacji, która pobiera identyfikator pierwszego interfejsu a następnie wyciąga z DHCP odpowiednią nazwę zepsuł mi trochę krwi. Najpierw musiałem sobie przypomnieć pewne podstawy Visual C++, potem musiałem załapać, że w nazwie interfejsu mam podać identyfikator. Następnie musiałem rozgryźć jak dynamicznie wyszukać ten identyfikator. Koniec końców udało mi się napisać mały programik w VC++, który pobiera odpowiednią opcje z DHCP i za pomocą newsida zmienia nazwę i SID. Poniżej kod, który pobiera id pierwszego interfejsu i następnie wyciąga z DHCP nazwę stacji.  Przypominam iż z zawodu nie jestem programistą i na samym początku dążę do tego by kod działał wedle moich oczekiwaniami. Następnie jak mam czas to staram się go upiększać. W kodzie częściowo starałem się wykorzystać przykłady dostępne na stronach MSDN.

#include < winsock2.h>
#include < iphlpapi.h >
#include < stdio.h >
#include < stdlib.h >
#include < windows.h >
#include < dhcpcsdk.h >
#include < string >
#include < wchar.h >
#pragma comment( lib, "dhcpcsvc.lib" )
#pragma comment(lib, "IPHLPAPI.lib")
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))

int __cdecl main()
{
	CONST int iAdapterIDLenght= 260;
	CONST int iHostnameLenght=60;
	int dw;
	CHAR pszHostNameBuf[iHostnameLenght];
	DWORD dwError, dwSize;
	CHAR TmpBuffer[iHostnameLenght];
	WCHAR wcAdapterName[iAdapterIDLenght];
    PIP_ADAPTER_INFO pAdapterInfo;
    PIP_ADAPTER_INFO pAdapter = NULL;
    DWORD dwRetVal = 0;
	ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);

    pAdapterInfo = (IP_ADAPTER_INFO *) MALLOC(sizeof (IP_ADAPTER_INFO));
    if (pAdapterInfo == NULL)
	{
        printf("Error allocating memory needed to call GetAdaptersinfo\n");
        return 1;
    }
    if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW)
	{
        FREE(pAdapterInfo);
        pAdapterInfo = (IP_ADAPTER_INFO *) MALLOC(ulOutBufLen);
        if (pAdapterInfo == NULL)
		{
            printf("Error allocating memory needed to call GetAdaptersinfo\n");
            return 1;
        }
    }

    if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR)
	{
        pAdapter = pAdapterInfo;
		dw = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pAdapter->AdapterName, -1, wcAdapterName, 0);
		MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pAdapter->AdapterName, -1, wcAdapterName, dw);

		DHCPCAPI_PARAMS DhcpApiHostNameParams = {
				0,                // Flags
				OPTION_HOST_NAME, // OptionId
				FALSE,            // vendor specific?
				NULL,             // data filled in on return
				0                 // nBytes
			};
		DHCPCAPI_PARAMS_ARRAY RequestParams = {
            1,  // only one option to request
            &DhcpApiHostNameParams
        };

		DHCPCAPI_PARAMS_ARRAY SendParams = {0,NULL};

		dwSize = sizeof(TmpBuffer);
		dwError = DhcpRequestParams(
            DHCPCAPI_REQUEST_SYNCHRONOUS, // Flags
            NULL,                         // Reserved
            wcAdapterName,					// Adapter Name
            NULL,                         // not using class id
	           SendParams,		          // sent parameters
            RequestParams,                // requesting params
            (PBYTE) TmpBuffer,            // buffer
            &dwSize,                      // buffer size
            NULL                          // Request ID
        );

		if( ERROR_MORE_DATA == dwError )
		{
			printf("Error: %s",dwError);
		}

		if( NO_ERROR == dwError )
		{

            if( DhcpApiHostNameParams.nBytesData )
            {

                CopyMemory(pszHostNameBuf, DhcpApiHostNameParams.Data,DhcpApiHostNameParams.nBytesData);
                pszHostNameBuf[DhcpApiHostNameParams.nBytesData] = '\0';
				printf("(12) DHCP Host Name: %s\n",pszHostNameBuf);
                return 0;
            }
		}
		else
		{
			printf("Error: %u",dwError);
		}

	}
	else
	{
        printf("GetAdaptersInfo failed with error: %d\n", dwRetVal);

    }
    if (pAdapterInfo)
        FREE(pAdapterInfo);
	getchar();
    return 0;
} 

W wolnej chwili postaram się napisać małą bibliotekę do podpięcia pod C#, tak bym mógł pobrać dowolne opcje z DHCP.

Categories: C / C++, Oprogramowanie klienckie Tags:

Jak wylistować pliki…

January 25th, 2009 No comments

Tak się dziś zastanawiałem jak wygląda wylistowanie plików do których użytkownik XYZ ma jakieś uprawnienia. Da się to dość łatwo zrobić za pomocą vbs lub zwykłego batch’a jednak od pewnego czasu kaleczę trochę w PowerShellu i jeśli tylko mam okazję to staram się go zaprzęgnąć do pracy:)

 get-childitem d:\Code -recurse | get-acl |select-object path, accesstostring | where-object {$_.AccessToString -like "*XYZ*"}
Categories: PowerShell Tags:

Wyszukiwanie plików o określonym rozszerzeniu

January 18th, 2009 No comments

Jak w szybki sposób wyszukać pliki o określonym rozszerzeniu na wszystkich dostępnych dyskach:

Do notatnika wklejamy poniższy kod i zapisujemy go jako plik batch (wyszukaj.bat).

@echo off
  for /f "skip=9 tokens=3" %%i in ('echo list volume ^| diskpart') do ( 
 
  dir %%i:\*.* /S /B /X |find ".%1" 
 
  )

Po zapisaniu pliku odpalamy go z wiersza poleceń z podaniem rozszerzenia:

wyszukaj.bat txt

Chyba czas zabrać się na poważnie za powershell:)

Categories: Jezyki programowania Tags:

Jak uruchomić program co X sekund.

January 5th, 2009 5 comments

Załóżmy, że chcemy sobie odpalać notepad co 10 sekund jak tego dokonać?

Najprościej jest ściągnąć sobie program soon.exe, który był kiedyś zawarty w Resource Kit dla Windows NT

Tworzymy sobie prostego batcha o nazwie runnotepad.cmd:

soon 10 runnotepad.cmd

notepad.exe

Potem za pomocą skryptu logowania można uruchamiać naszego batcha raz a on sam będzie sie uruchamiał w kolko.

Szybkie wyszukiwanie dzierżawy w DHCP.

November 8th, 2008 No comments

Czasami dostaję informacje o problemach z niektórymi komputeram. Użytkownicy nie mają dostępu do zasobów sieciowych czy nie mają wyjścia na świat. Jest to spowodowane różnymi problemami, czasem sieć przed nimi broni NAP, czasem ktos wyciągnął wtyczkę a czasem komputer nie otrzymał IP z serwera DHCP.

Jeśli komputer nie otrzymuje dzierżawy to zaczyna się zabawa z wyszukiwaniem czy dany adres MAC został wpisany do rezerwacji. Zwykły snapin DHCP jak na razie nie pozwala nam jakoś sensownie wyszukiwać rezerwacji za pomocą adresów fizycznych. O ile dziesięć, pięćdziesiąt adresów można szybko przepatrzeć to sto, dwieście czy tysiąc rezerwacji nie ogląda się zbyt dobrze:(

Na szczęście da się temu wszystkiemu zaradzić za pomocą różnych skryptów. Najprościej jest wykorzystać netsh i findstr. Minusem tej metody jest wyplucie z netsh do pamięci wszystkich rezerwacji z serwera DHCP.

Przykład:

netsh dhcp server \\"nazwa_serwera" scope "nazwa_przedzialu" show reservedip | findstr "adres_fizyczny"
Adres fizyczny musi byc postaci 00-0f-0d-01-01-02

Gdzieś jeszcze mam lepszy odpowiednik w C# jak go znajdę w pracy to wstawie do plików.