16.11.2018

Komut satırından clipboard kullanımı

Bir komutun çıktısını komut satırı penceresinde uzun uzun işaretleyip kopyalamaktansa pipe ile clipboard'a aktarmayı nasıl yaparım diye ararken şu sayfaya denk geldim. Aslında eski komu satırı ile bu işi yaparken clip.exe iş görüyor. Örneğin
dir *.txt /b /s | clip
ile mevcut klasörün tüm alt klasörlerindeki txt dosyalarının isimlerini clipboard'a kopyalayabilirim.

Peki bunun eşdeğeri powershell'de var mıdır diye arıyordum ki arkadaş 3 senelik çalışmasının sonuçlarını paylaşmış, sağolsun. Ama altına Nihayet Mark Minasi bile gelip yorum yapmış; sanıyorum ki gerçek Mark Minasi. Demiş ki, WMF 5.0 ile Get-Clipboard ve Set-Clipboard cmdlet'leri geldi. WMF 5.0 de Powershell 5 demek oluyor.

Şu an itibariyle en son WMF 5.1 var ve yükleyince şu oluyor:
PS> $PSVersionTable
Name                           Value
----                           -----
PSVersion                      5.0.10586.117
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.10586.117
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

TL;DR
Aynı işi powershell'de yapmak için

dir *.txt -recurse | Set-Clipboard
yeterli.

Komut satırını her açtığımda çalışsın

Powershell'de her açtığımda çalışmasını istediğim bazı komutlarım vardı. Onları profil Belgelerim klasörümün altındaki WindowsPowerShell altına profile.ps1 dosyasına kaydettim (ayrıca bu klasörün altında Modules\[modülismi]\[modülismi].psm1 gibi bir klasöre de kendi modülümü oluşturdum).

Benzer şekilde komut satırı penceresi için de her seferinde çalışacak bir komut dosyası oluşturmak istedim. Bunun cevabını da şurada buldum. Buna göre
HKEY_CURRENT_USER\Software\Microsoft\Command Processor
altına AutoRun adında REG_EXPAND_SZ tipinde bir değer yaratıp adını da örneğin %USERPROFILE%\init.cmd vererek profil klasörümün altındaki init.cmd dosyasının çalışmasını sağlayabilirim. Bu işi tek bir komutta yapmak istersek bunun yolu da
reg add "HKCU\Software\Microsoft\Command Processor" /v AutoRun ^
  /t REG_EXPAND_SZ /d "%"USERPROFILE"%\init.cmd" /f
şeklinde verilmiş. Bu da güzel. Örneğin bir ortam değişkeni yaratıp bir de alias yaratmak için içeriğini şöyle oluşturabiliriz:

@echo off
set gdrv="C:\Users\metin\Google Drive"
doskey ls=dir /on
Hep linux zırvası bunlar.

---
[1] https://stackoverflow.com/questions/17404165/how-to-run-a-command-on-command-prompt-startup-in-windows
[2] https://stackoverflow.com/questions/20530996/aliases-in-windows-command-prompt
[3] https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc779439(v=ws.10)

15.11.2018

Windows'da sembolik ve hard link'ler

Windows'da kısayol yaratmanın düz yolu kısayolu kopyalayıp, yapıştırırken "kısayol yapıştır"ı seçmek. Bu şekilde aslında lnk uzantılı bir dosya yaratılır. Bu kısayol çift tıklandığında bu bu lnk uzantılı dosyanın işaret ettiği dosya çalıştırılır.

Bundan başka bir de sembolik link yaratma var. C:\Windows\system32\notepad.exe'nin sembolik linkini yaratmak için komut satırında şunları yazmak gerek (mklink'i yönetici hakları ile çalıştırarak):
mklink notdefteri C:\Windows\system32\notepad.exe
Bu iki yöntem ile mevcut klasörde yaratılan dosyaların farkı aşağıdaki gibi olacak
15.11.2018  13:27    <SYMLINK>      notdefteri [C:\Windows\System32\notepad.exe]
15.11.2018  13:28             1.191 notdefteri.lnk
İlki sembolik kısayol (<SYMLINK> olarak görülüyor), diğeri "kısayolu yapıştır" yöntemi ile oluşturulan.

Bir klasörün sembolink link'ini oluşturmak için /D anahtarı kullanılmalı.

mklink /D Belgelerim C:\Users\metin\Documents

Bu yöntemle oluşturulan kısayol şöyle gözükür (<SYMLINKD>):
15.11.2018  13:34    <SYMLINKD>     tf [E:\testfolder]
Sembolik linkler silinse bile notepad.exe dosyası silinmez. Çünkü bunlar asıl notepad.exe dosyasını gösteren işaretçilerdir. Ama notepad.exe silinirse o zaman sembolik linkler anlamsız birer işaretçi olurlar.

Dosya sistemindeki sembolik linkleri bulmak için dir komutunu /AL ile kullanmak gerek:
dir /AL
Eğer bir klasörün alt klasörlerindeki bütün dosyaları bulmak istiyorsak
dir /AL /S C:\Users
kullanılabilir. Aynı şeyi powershell ile yapmak istersek
Get-ChildItem | where {$_.Attributes -match "ReparsePoint"}
Powershell ile dir komutu (Get-ChildItem) kullanıldığında ilk sütunda görüntülenen Mode alanındaki dosyanın öznitelikleri (attributes) listelenir. Bu özniteliklerden en sağdaki veri dosyanın bir reparsepoint olup olmadığını gösterir. Sembolik linkler için bu kısımda bir "l" harfi gösterilir. Örnek:
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d----l       15.11.2018     13:34                tf
-a---l       15.11.2018     13:27              0 notdefter
Bundan başka bir de hard link'ler var. Bunun için mklink'i  /H anahtarını ile kullanmak lazım:
mklink /H hardlink dosya.exe
Bunun sonucunda diskin üzerindeki aynı veriyi gösteren iki dosya sistemi girişimiz olur. Bunlardan biri silinse bile asıl dosya verisi silinmez. Hard link'in hedefi aynı disk bölümü içinde olmalıdır.

Hard link'ler klasörler için olmaz. Klasörler için benzer kavram junction'dır. Başka bir disk bölümünde yer alan klasör için junction yaratılabilir. Örnek:
mklink /J junction D:\testfolder
Bu konuları özetlemek için ss64.com sitesinden alınma aşağıdaki tablo faydalı olabilir:

Windows komut satırından exe dosyası sürüm numarası sorgulama

Hızlı bir şekilde, çoğunlukla da uzaktaki bir sistemdeki bir exe dosyasının sürüm bilgisini öğrenmek istediğimde şu yöntemlerden birini kullanıyorum.

Düz Windows ortamı, ek bir araç kullanmadan, doğrudan komut satırından:

wmic datafile where name='C:\\windows\\notepad.exe' get Version
Bu yöntem ile ağ üzerinden uzaktaki dosya sorgusu mümkün değil. datafile parametresi UNC yolları desteklemiyor.

Ağ üzerinden sorgu yapabilmek için Sysinternals'ın sigcheck komutuna ihtiyaç var. Kullanım şöyle:
sigcheck -nobanner -n \\uzakbilgisayar\c$\Windows\notepad.exe
Powershell ile yapmak için ise
(Get-Item \\uzakbilgisayar\c$\Windows\notepad.exe).VersionInfo.Fileversion
kullanılabilir.