Pokazywanie postów oznaczonych etykietą windows. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą windows. Pokaż wszystkie posty

sobota, 15 sierpnia 2015

Exportowanie praw dostępu w PS

Krótki kodzik, ale przydatny przy sprawdzaniu praw dostępu do plików. Chcesz wiedzieć jakie są uprawnienia - wystarczy, że uruchomisz ten PS skrypt, a on wygeneruje csv z uprawnieniami.

function Export-IOPermissions
{
    [cmdletbinding()]
    param(
        [ValidateScript({Test-Path $_ -PathType 'Container'})]    
        [string]
        $dir='.'    
        , 
        [ValidateNotNullOrEmpty()]
        [string]
        $outputcsv = '..\permissions.csv'
        ,
        [ValidateNotNullOrEmpty()]
        [string]
        $Delimiter = ','
    )

$prop = @('Path', 'Group', 'Owner', 'Sddl', 'PSChildName',  'AccessRightType', 'AccessRuleType', 'AreAccessRulesCanonical', 'AreAccessRulesProtected', 'AreAuditRulesCanonical', 'AreAuditRulesProtected', 'AuditRuleType', 'AccessToString', 'AuditToString') 
 
    if( Test-path $outputcsv)
    {
        Remove-Item -path $outputcsv | out-null
    }
gci -Recurse -path $dir  | Get-Acl | select -Property $prop  -Expand Access  |  Sort-Object  -Property, Path, FileSystemRights, IdentityReference | Export-Csv -Path $outputcsv -Delimiter $Delimiter  -NoTypeInformation -Force

}



piątek, 31 lipca 2015

Sposób na przeglądanie folderów w powolnej sieci

Jeżeli zdarzyło Ci się, że musiałeś poznać strukturę folderów w sieci, a połączenie było super wolne to, to rozwiązanie spodoba Ci się.
Wpadłem na nie dopiero pod koniec mojego poprzedniego projektu. Potrzebowałem informacji jak wygląda struktura folderów, nie potrzebowałem informacji o plikach, a połączenie było tak powolne, że krew mnie zalewała :)

Z pomocą przyszło do mnie polecenie xcopy:

xcopy /t /e  \\Shared\ c:\toCheck\

To polecenie kopiuje foldery z \\Shared\ do c:\toCheck\.
Działa bardzo szybko bo nie musi przetwarzać plików, a tylko info. o strukturze folderów.

środa, 22 lipca 2015

Zmapowane dyski sieciowe

Na komputerach zdalnych mam zmapowane dyski sieciowy i czasami muszę przesłać ścieżkę.
Poniższa funkcja w PS zwróci Ci wszystkie zmapowane dyski:

function Get-NetworkDrive([string]$ln = "Z", [switch]$all, [string[]]$computername='.') {
if($all) {
    gwmi  -Class Win32_NetworkConnection  -computername  $computername 
    }
else {
    gwmi  -Class Win32_NetworkConnection  -Filter "LocalName like `'$ln%`'"  -computername $computername 
    }
}

Przykład działania funkcji na komputerze lokalnym wygląda tak:
Get-NetworkDrive P

wtorek, 14 lipca 2015

Zabijanie zawieszonego serwisu

Zawieszony serwis to zły serwis. Nie można go stopować ani zrestartować.
Jedyne co nam pozostało to ubicie serwisu.

To rozwiązanie znalazłem z tej strony
Właśnie takiego prostego rozwiązania szukałem.

Najpierw wyświetlasz informację o serwisie, który zawiesił się:
sc queryex $service_name$
Zapisujesz identyfikator procesu (PID)

A później wywołujesz komendę do ubijania procesu:
taskkill /f /pid $pid$

sobota, 9 maja 2015

For loop dla msbuild

Jak będziesz chciał uruchomić kilka razy dany proces to możesz wykorzystać polecenia for. Ja tak muszę z budowaniem projektów w .NETcie. Musze 2 razy uruchomić msbuild'a. Niektóre projekty nie maja referencji do innych projektów w solucji, ale do zbudowanych bibliotek w specjalnym folderze. Problem też może być jak jedno budowanie projektu potrzebuje dużo czasu (dajmy na to 25 minut) i w każdym momencie może wystąpić błąd.

Polecenie do dwukrotnego budowania jest poniżej:
for /L %n in (1,1,2) do ( msbuild myProject.sln /m )​

Takie proste, a tak upraszcza życie :)

środa, 12 listopada 2014

Wyjście na notatnik czyli oczekiwany out-notepad w PS

Bawiąc się z PowerShellem, zauważyłem brak wysłania rezultatów do notatnika w stylu Out-GridView. Postanowiłem napisać skrypcik, który by to umożliwiał. Na samym początku jest potrzebna funkcja do znajdywania okna z aplikacją oraz wysyłania tekstu do niej. Skorzystamy z biblioteki user32.dll. Skrypt wyglada następująco:

$User32MethodDefinition = @'
[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);    
'@

$User32 = Add-Type -MemberDefinition $User32MethodDefinition -Name 'user32' -Namespace 'Win32' -PassThru
Za każdym razem jak uruchomimy skrypt to będziemy musieli stworzyć nowy obiekt $user32 (i będziemy musieli wiedzieć czy obiekt ma wymagane metody). Dlatego potrzebna nam będzie funkcja sprawdzająca metody statyczne na obiekcie
function Test-StaticMembers
{
    param(
    [ValidateNotNull()]
    $objectToTest
    , 
    [string[]]
    $members)

    [array]$result = $objectToTest.GetMembers() |
        ? {$_.IsStatic -eq $true -and $_.IsPublic -eq $true} |
        ? {$_.IsAbstract -eq $false -and $_.IsConstructor -eq $false} |
        ? { $members -contains $_.Name}

    if( $result.Count -eq $members.Count)
    { return $true}
    
    throw "Not all member are in object. Searching for members: $members"
}
Sprawdzanie obiektu wygląda następująco:
if( ! $User32 -OR !(Test-StaticMembers -objectToTest  $User32   -members 'FindWindowEx','SendMessage' ) )
{
    $User32 = Add-Type -MemberDefinition $User32MethodDefinition -Name 'user32' -Namespace 'Win32' -PassThru
}
Teraz będziemy mogli stworzyć funkcje do wysyłania outputu tekstu do dowolnej aplikacji:
Function Out-Applciation
{
    Param(
        [Parameter(ValueFromPipeline = $true)] 
        [string]
        $text
        ,
        [switch]
        $toAll,
        [switch]
        $passResult
        ,
        [string]
        $appName
    )
    Begin{
            $textArray = @()
            $intPtr = New-Object 'IntPtr' -ArgumentList '0'

            if($toAll)
            {
                $appProcesses = Get-Process -Name $appName -ErrorAction SilentlyContinue 
            }
            else
            {
                $appProcesses =@( Start-Process -FilePath $appName -PassThru )
            }

            #check if process list exist
            if(! $appProcesses)
            {
                Start-Process -FilePath $appName 
                $appProcesses = Get-Process -Name $appName 
            }
    }
    Process{
        $textArray += $text
    }
    End{
        $textString = $textArray  | out-string
        $appProcesses | %{
           $findWindowExTryCounter = 0
           while(!$windowExChild -OR $windowExChild -eq 0)
           {
            $windowExChild =  $User32::FindWindowEx($_.MainWindowHandle, $intPtr,'Edit', $null )
            
            #if FindWindowEx will not work
            $findWindowExTryCounter++
            if($findWindowExTryCounter -gt 100)
            {
                throw "Can not find window $($_.MainWindowHandle) for $appName"
            }
            else
            {
                Start-Sleep -Milliseconds 100 
            }
           }
           $result = $User32::SendMessage($windowExChild, '0x000C', 0,  $textString )
           
           if($passResult) 
           {$result} #if 1 then is has been send
        }
    }
}
Do tego stworzymy pomocna funkcję do wysyłania wyjścia na notepad:
function Out-Notepad
{
    param(
        [switch]
        $toAll,
        [switch]
        $passResult
    )
    Begin{
        $appName = 'notepad'
    }
    End{
        $input | Out-Applciation -toAll:$toAll -passResult:$passResult -appName $appName
    }
}

Dla przykładu zastosowania out-notepad, pomocna nam będzie funkcja numerująca stringi w kolekcji:
function Numerate-String
{
     Param(
        [Parameter(ValueFromPipeline = $true)] 
        [string]
        $text,

        [string]
        $seperator=':'
        )

    begin{
        $count =0
    }
    process{
            $result = "$count $seperator"+ [System.Environment]::NewLine + $text
            $count++
            return $result
        }
}​

A wywołanie może byglądać następująco:
gc applicationName.log | Numerate-String | Out-Notepad

środa, 2 lipca 2014

Sprawdzenie wolnego obszaru na dysku


Tak często potrzebuje sprawdzać wolny obszar na dysku, że postanowiłem zamieścić ten krótki kod:
gwmi win32_logicaldisk | select DeviceID, @{n="FreeSpace (GB)"; e={$_.FreeSpace/1GB}},  @{n="Size (GB)"; e={$_.Size/1GB}}

Oprócz tej komendy chciałbym Ci przedstawić tool o nazwie WinDirStat. Oczywiście można pobrać ten tool z chocolatey.

niedziela, 4 maja 2014

Pobranie ról użytkownika w PS

Kiedy pracujesz zdalnie przez konsole PS i nie możesz uruchomić polecenia PS to być może nie masz uprawnień. Aby sprawdzić z jakimi uprawnieniami pracujesz na konsoli wystarczy uruchomić poleceni Get-Role. Implementacja tej funkcji jest poniżej:
function Get-Role
{
param(
$user =  
$([Security.Principal.WindowsIdentity]::GetCurrent()),

[Security.Principal.WindowsBuiltinRole[]]$role= 
$([Security.Principal.WindowsBuiltinRole].GetEnumValues())
)
 $userPrincipal = New-Object Security.Principal.WindowsPrincipal $user
 $role | %{
    return New-Object PSOBJECT  | 
Add-Member -MemberType NoteProperty 
-Name "Role" -Value $_  
-PassThru |
               
Add-Member -MemberType NoteProperty 
-Name "IsIn" -Value ($userPrincipal.IsInRole($_)) 
-PassThru
 }
}

Jak widać użytkownik nie ma praw administratora.
Gdy tą samą funkcję uruchomisz na konsoli z prawami admina to twój użytkownik też jest w roli administratora.

środa, 30 kwietnia 2014

Restartowanie PowerShell Remoting

Kiedy korzystasz z PSRemoting to pewnie zauważyłeś, że komenda Disable-PSRemoting tak na prawdę nie gasi serwisu i nie usuwa listenerów. Niestety musimy to wykonywać ręcznie. Co prawda przydał by się parametr w poleceniu Disable-PSRemoting.

Poniższy kod wyłącza PSRemoting, serwis i usuwa listenerów:
function Restart-PSRemoting
{
        param(
        [Switch]$restartService,
        [Switch]$removeListeners,
        [Switch]$WhatIf,
        [Switch]$enable,
        [int[]]$listenerPorts=(5985,5986)
        )
        Disable-PSRemoting -Force -WhatIf:$WhatIf

        if($restartService)
        {
            Set-Service winrm -StartupType Manual -WhatIf:$WhatIf
            Stop-Service winrm -WhatIf:$WhatIf
        }

        if($removeListeners)
        {
            gci WSMan:\localhost\Listener -Recurse  | 
            %{ $_.PSPath} | 
            ?{ 
               $port = (gci "$_\port").Value 
               $listenerPorts -contains $port
            }|
            Remove-Item -WhatIf:$WhatIf
        }
        if($enable)
        {
            Enable-PSRemoting -Force -WhatIf:$WhatIf
        }
}

Aby sprawić co zrobi polecenie wystarczy wywołać polecenie z parametrem WhatIF
Restart-PSRemoting -WhatIf -removeListeners -enable -restartService

poniedziałek, 24 marca 2014

Pobieranie machine.config z poziomu PS

Machine.config jest bardzo ważnym plikiem. Takie pliki konfiguracyjne jak app.config czy web.config 'dziedziczą' po machine.config. Aplikacja .NET odczytuje ustawienia jakie znajdują się w machine.config, a później z innych plików konfiguracyjnych. Informacje z machine.config są dostępne dla wszystkich aplikacji na komputerze i dlatego mogą zawierać takie informację jak connection string czy informacje o serwerez SMTP.

Jak wiemy PS też jest aplikacją, która korzysta z machine.config. Poniżej zamieściłem skrypt do odczytu informacji z tego pliku:
function Get-MachineConfig
{
    param(
    [switch] $location,
    [switch] $content,
    [switch] $xml,
    [switch] $connectionStrings)

    $retLocation = [System.Runtime.InteropServices.RuntimeEnvironment]::SystemConfigurationFile
    if($location)
    {
        $retLocation 
    }

    $retContent = gc $retLocation
    if($content)
    {
       $retContent 
    }

    $retXml = [xml]$retContent 
    if($xml)
    {
         $retXml
    }

    if($connectionStrings)
    {
       $retXml.configuration.connectionStrings.add
    }
}


Na uwagę zasługuje parametr, który zwraca ścieżkę do używanego pliku konfiguracyjnego:
Get-MachineConfig -location

Oraz parametr do pobierania informacji o dostępnych połączeniach do baz danych:
Get-MachineConfig -connectionStrings

czwartek, 20 marca 2014

Wielkość folderów w PS

Zastanawiałeś się jak można sprawdzić wielkość folderów w podkatalogach? Poniżej jest kod w PS, który wyświetla wielkość folderów w podkatalogach.

function Show-SpaceUsage
{
    [CmdLetBinding()]
    param(
        [Parameter(Mandatory=$true, Position=0)]  
        [ValidateScript({Test-Path $_ })]
        [string]$path,

        [decimal]$parentSize=0,

        [ValidateNotNullOrEmpty()]
        [string]$format = "N2"
    )
    $size = (Get-ChildItem $path -Recurse | ?{$_.PSIsContainer -eq $false} | measure -property length -sum).sum
   
    $parentPercentage =1
    if($parentSize -ne 0)
    {
       $parentPercentage = $size / $parentSize  
    }

    $item = gi $path
    new-object PSObject | 
            Add-Member -PassThru -MemberType NoteProperty -Name  Path  -Value $item.FullName |
            Add-Member -PassThru -MemberType NoteProperty -Name  Name  -Value $item.Name |
            Add-Member -PassThru -MemberType NoteProperty -Name  GB  -Value ("{0:$format}" -f ($size / 1GB)) |
            Add-Member -PassThru -MemberType NoteProperty -Name  MB  -Value ("{0:$format}" -f ($size / 1MB)) |
            Add-Member -PassThru -MemberType NoteProperty -Name  KB  -Value ("{0:$format}" -f ($size / 1KB)) |
            Add-Member -PassThru -MemberType NoteProperty -Name  "Percentage of Parent" -Value ("{0:$format}" -f $parentPercentage)

    $dirs =  Get-ChildItem $path | ?{$_.PSIsContainer -eq $True} | sort Name
    $dirs | %{
        Show-SpaceUsage -path $_.FullName -parentSize  $size
        Write-verbose ""
    }
}

Wyniki są sformatowane do tabeli:
Show-SpaceUsage -path "." -Verbose | Format-Table

Oczywiście można wyniki wyeksportować do csv i tam już posortować po największych folderach:
Show-SpaceUsage -path "." | Export-Csv -path "result.csv" -Delimiter ';' -NoTypeInformation -Encoding ASCII 

sobota, 15 marca 2014

WhoAmI - pierwsze polecenie na nowym komputerze

Jednym z pierwszych poleceń PowerShell wywołanych na Twoim nowym komputerze powinno być polecenie WhoAmI:
PS>WhoAmI 
<computer_name>\<user_name>
Można uzyskać listę wszystkich grup do których należysz (do tego możesz wyeksportować do csv'ki):
WhoAmI /GROUPS /FO CSV /NH
Oraz możesz uzyskać dodatkową listę uprawnień:
PS>WhoAmI /PRIV

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                           State   
============================= ===================================== ========
SeShutdownPrivilege           Zamknij system                        Disabled
SeChangeNotifyPrivilege       Obejd« sprawdzanie przy przechodzeniu Enabled 
SeUndockPrivilege             Usuä komputer ze stacji dokujĄcej     Disabled
SeIncreaseWorkingSetPrivilege Zwi©ksz zestaw roboczy procesu        Disabled
SeTimeZonePrivilege           Zmieä stref© czasowĄ                  Disabled

Wszystko w porządku pod warunkiem, że posiadasz system nowszy niż Windows XP. Jeżeli jednak nie posiadasz takiego systemu to będziesz musiał sam napisać taki program/skrypt. Na przykład w PowerShellu będzie wyglądał tak:
function WhoAmIPS
{
 [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
}

Aby uzyskać listę wszystkich grup do których należysz to powinieneś wywołać poniższą funkcję:
function WhatGroupAmIIn
{
    $user = [System.Security.Principal.WindowsIdentity]::GetCurrent()
    $nt = "System.Security.Principal.NTAccount" -as [type]
    $user.Groups | 
    ForEach-Object { $_.translate($NT)}
}

środa, 12 marca 2014

Pobieranie z GAC za pomocą PowerShell

Tak się zastanawiam, dlaczego PowerShell nie ma możliwości pobrania danych z GAC. PS wymaga zainstalowanego .NET, a najnowsze systemy z automatu mają ten framwork zainstalowany. Niestety jesteśmy zmuszeni do używania GacUtil.exe (Global Assembly Cache Tool). Napisałem skrypt do zwracania elementów z GACy.

function Get-GAC
{
    [CmdletBinding()]
    param()

& 'C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\gacutil.exe' /L |
? { $_ -match '^  ([\w\.]+,.*)$' } |
    % { 
        $fullName = ($Matches[1])
        try
        {
           $assembly = [System.Reflection.Assembly]::Load($fullName)
           $assembyName = $assembly.GetName()

           new-object PSObject -prop @{ 
                FullName = $assembly.FullName; 
                GAC = $assembly.GlobalAssemblyCache;
                Version = $assembly.ImageRuntimeVersion;
                FullyTrusted = $assembly.IsFullyTrusted;
                Location = $assembly.Location;
                Name = $assembyName.name;
                ReferencedAssemblie = $assembly.GetReferencedAssemblies();
                Token = ($assembyName.GetPublicKeyToken() |  foreach {$_.ToString("X2")}) -join '';
                HashAlgorithm = $assembyName.HashAlgorithm;
                CultureInfo = $assembyName.CultureInfo;
           }
        }
        catch [system.exception]
        {
            Write-Verbose $_
        }
    }| sort Name -unique 
}

Przykład użycia jest poniżej. Dodatkowo dodajemy parametr verbose, gdyż nie wszystkie biblioteczki są załadowywane. Jeszcze troszkę będę musiał przy tym posiedzieć i sprawdzić dlaczego nie wszystko zostaje załadowane. Może ty masz jakiś pomysł??
( Get-GAC -Verbose ) | out-gridview

sobota, 2 marca 2013

Zamykanie Windows 8

Musze się przyznać, że jak pierwszy raz uruchomiłem Windows 8 to nie wiedziałem, gdzie jest przycisk do zamykania komputera. Po pewnym czasie w końcu znalazłem. Jeżeli jesteś użytkownikiem Windows 8, to miałeś może taki problem jak ja??



W każdym razie nie o problemach szukania przycisku chciałbym napisać, ale o szybkim zamykaniu systemu.
Na samym początku stwórz skrót ma pulpicie.

Jako program wykonywalny wpisz:

shutdown.exe /s /t 00

Inne opcje są podane na tej stronie.

Polecam wybranie sobie ikonki.


Zaznacz sobie prawym przyciskiem myszy i wybierz "Przypnij do ekranu startowego" ("Pin to Start").



W menu Start przenieś przycisk tam gdzie chcesz. Oczywiście możesz dodać inne opcje zamykania (np. restartowanie).


Na końcu możesz jeszcze usunąć te skróty, które stworzyłeś na pulpicie - usunięcie ich nie wpływa na funkcjonalność okna Start.

wtorek, 10 kwietnia 2012

Co nowego w Visual Studio 2011

I stało się. Musiałem przeinstalować mój stary system. Skoro wszystko usunąłem i na nowo musiałem zainstalować VS to pomyślałem sobie, że przetestuje Windows 8 oraz Visual Studio 2011. Pierwszy problem na jaki natrafiłem to instalacja systemu przez Boot Campa. Mam macbooka i obecna wersja Boot Campa nie pozwala na instalacje systemu nowszego niż Windows 7. Po tej operacji mogłem zaktualizować system do Windows 8. Na samym początku troszkę się przeraziłem bo nie wiedziałem, gdzie podział się stary dobry pulpit, a nawet nie wiedziałem jak się wyłącza komputer :)




Dla systemu Windows 8 jest dużo problemów z integracją z macbookiem. Są problemy m.in. z ustawieniem jasności (co jakiś czas ekran sam się gasi), działaniem sprzętu na usb czy po prostu klawiatura przestaje działać. Nie spotkałem się z tymi problemami w trakcie korzystania z Windows 7.


Po krótkim zapoznaniu się z systemem, zająłem się VS. Od razu widać, że instalacja całkowicie inaczej wygląda.



Ikony w VS są łagodniejsze dla oka. Kiedy w Solution Explorer najedziemy kursorem na zdjęcie to dostaniemy podgląd. Przy edycji tekstu z kolorem w pliku .css możemy zobaczyć ten kolor. Do VS dodano Unit Test Explorer (zamiast Test View i Test Results), w którym można odpalić testy oraz zobaczyć pokrycie kodu. W Solution Explorer można przeglądać metody danej klasy. W prawym górnym rogu jest Quick Lunch (Ctrl + Q), w którym możemy w szybki sposób wykonać polecenie VS. Jeżeli debugujemy stronę to już nie musimy za każdym razem ustawiać domyślną przeglądarkę, ale mamy możliwość wybory przeglądarki do debugowania. Możemy ekstraktować nie tylko metody, ale również kod w aspx do kontrolki. Poniżej zamieszczam zdjęcia, aby przybliżyć nowy wygląd VS.

















Więcej o nowych rzeczach w VS można znaleźć tutaj oraz tutaj. Mam nowe VS to mam nadzieję, że znajdę troszkę czas na naukę metro style:)

poniedziałek, 26 września 2011

Metro Style - Nowy interfejs dla Windows 8

Konferencja BUILD już się skończyła i to co Microsoft przygotował dla developerów całkowicie mnie zszokowało. Nowy interfejs dla Windows 8.



Microsoft zdał sobie sprawę, że system operacyjny dla różnych urządzeń powinien być jeden. Diametralne zmiany, które ujednolicają obsługę zwyczajnego notebooka, tableta czy telefonu komórkowego, mogą na samym początku wzbudzać strach. Pamiętam, że tak samo było z Ribbonem. Większość osób, krytykowało nowy interface, ale po któtkim czasie korzystania z niego uważali, że wstążka jest genialna :)





Więcej o Metro Style oraz o samym Windows 8 można znaleźć w poniższym filmiku.




Po obejrzeniu takiego filmiku, jedyne co mi się nasuwa to pytanie:
Jak nadążyć za technologią??