21.03.2025

The package provider requires 'PackageManagement' and 'Provider' tags hatası

Bir makinede powershell ile PowershellGallery.com'dan bir modül kurmak istediğimde

Install-Module -Name PSWritePDF

şöyle bir hata alıyordum:

PackageManagement\Install-PackageProvider : No match was found for the specified search criteria for the

provider 'NuGet'. The package provider requires 'PackageManagement' and 'Provider' tags. Please check if the

specified package has the tags.

At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1:7468 char:21

+ ...     $null = PackageManagement\Install-PackageProvider -Name $script:N ...

+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidArgument: (Microsoft.Power...PackageProvider:InstallPackageProvider) [I

   nstall-PackageProvider], Exception

    + FullyQualifiedErrorId : NoMatchFoundForProvider,Microsoft.PowerShell.PackageManagement.Cmdlets.Install

   PackageProvider


PackageManagement\Import-PackageProvider : No match was found for the specified search criteria and provider

name 'NuGet'. Try 'Get-PackageProvider -ListAvailable' to see if the provider exists on the system.

At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1:7474 char:21

+ ...     $null = PackageManagement\Import-PackageProvider -Name $script:Nu ...

+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidData: (NuGet:String) [Import-PackageProvider], Exception

    + FullyQualifiedErrorId : NoMatchFoundForCriteria,Microsoft.PowerShell.PackageManagement.Cmdlets.ImportP

   ackageProvider


WARNING: Network connectivity may not be available, unable to reach remote sources.

WARNING: Unable to bootstrap the required package provider due to problems with network connectivity. Please

fix your network connection. If this is not possible, refer to 'Get-Help Install-PackageProvider' or

https:/go.microsoft.com/fwlink/?LinkId=626941 for guidance on installing the package provider manually.

WARNING: Unable to download from URI 'https://go.microsoft.com/fwlink/?LinkID=627338&clcid=0x409' to ''.      WARNING: Unable to download the list of available providers. Check your internet connection.                  PackageManagement\Get-PackageProvider : Unable to find package provider 'NuGet'. It may not be imported yet.  Try 'Get-PackageProvider -ListAvailable'.                                                                     At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1:7478 char:30                + ... tProvider = PackageManagement\Get-PackageProvider -Name $script:NuGet ...

+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ObjectNotFound: (Microsoft.Power...PackageProvider:GetPackageProvider) [Get-Pa

   ckageProvider], Exception

    + FullyQualifiedErrorId : UnknownProviderFromActivatedList,Microsoft.PowerShell.PackageManagement.Cmdlet

   s.GetPackageProvider


Install-Module : NuGet provider is required to interact with NuGet-based repositories. Please ensure that

'2.8.5.201' or newer version of NuGet provider is installed.                                                  At line:1 char:1                                                                                              + Install-Module -Name PSWritePDF                                                                             + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                                                 + CategoryInfo          : InvalidOperation: (:) [Install-Module], InvalidOperationException                   + FullyQualifiedErrorId : CouldNotInstallNuGetProvider,Install-Module

Çözüm olarak şu sitede gösterildiği gibi

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

ile TLS 1.2'yi Service Point Manager olarak ayarladıktan sonra asıl kurmak istediğim PSWritePDF'i kurmayı başardım.

19.03.2025

Timeout özelliği olan bir powershell ping fonksiyonu

Powershell'de Test-Connection cmlet'i ping yerine kullanılabilir. Ping'e benzer şekilde 4 adet ICMP paketi gönderir ve cevabını bekler. Bazen betiklerin içinde hedef cihazın canlı olup olmadığını anlamak için

Test-Connection -Computername hedef -Quiet -Count 1

gibi bir komut kullanırım, sadece True veya False dönen. Hedef cihaz açıksa ve ping'e cevap veriyorsa hemen True döner. Ama hedef cihaz kapalıysa False dönmesi uzun sürer. Powershell 5.1'de Test-Connection'ın bir timeout parametresi de yok. Onun için şöyle bir fonksiyon işimi görüyor:

function Test-ICMP {
    param (
        [string]$Computername = "8.8.8.8",
        [int]$Timeout = 1000  # Milisaniye
    )

    $ping = New-Object System.Net.NetworkInformation.Ping
    $task = $ping.SendPingAsync($Computername, $Timeout)

    $completed = [System.Threading.Tasks.Task]::WaitAny(@($task), $Timeout)

    if ($completed -eq 0) {
        # Ping işlemi tamamlandı, sonucu al
        $reply = $task.Result
        if ($reply.Status -eq "Success") {
            $True
        } else {
            $False
        }
    } else {
        # Timeout süresinden uzun sürdü
        $False
    }
}

Hiç bir parametre kullanmazsam varsayılan hedef olarak Google'ın birincil DNS sunucusu 8.8.8.8'e 1 adet ICMP request paketi gönderir ve 1000 ms bekler. Ama yerel ağdaki bir makinenin açık mı kapalı mı olduğunu anlamak için

Test-Connection -Computername hedef -Timeout 100

yazabilirim. 100 ms içinde açıksa True, kapalı (veya cevap dönmüyorsa) False cevabını alırım.

12.03.2025

Uzun powershell komutları tamamlanınca sesli uyarı versin

Powershell'de bazı komutların tamamlanması uzun sürebiliyor. Uzun sürsün, sorun değil. Ama bitince haberim olsa keşke diye düşünürken aklıma bir yöntem geldi.

Zaten profil dosyamın içinde en son komutun ne kadar sürdüğünü hesapladığım bir bölüm vardı.

    if ((Get-History).Length -gt 0)
    {
        $LastExecutionTime = [long]((Get-History)[-1].EndExecutionTime - (Get-History)[-1].StartExecutionTime).TotalMilliSeconds
    }

Her komut tamamlandığında bir sesli uyarı almak da istemiyorum. Ne zaman almak isterim diye kendime sordum, aldığım cevap 5 saniye oldu. Bana da mantıklı geldi. Bu if bloğunu şöyle güncelledim:

    if ((Get-History).Length -gt 0)
    {
        $LastExecutionTime = [long]((Get-History)[-1].EndExecutionTime - (Get-History)[-1].StartExecutionTime).TotalMilliSeconds
        if ($LastExecutionTime -gt 5000) {
            Play-Sound -Play "C:\Windows\Media\Windows Proximity Notification.wav"
        }
    }

Zaten Play-Sound diye bir fonksiyonum vardı. Yoksa onu da şu şekilde oluşturabilirdim:

function Play-Sound
{
    param
    (
        [string]$Play = "C:\Windows\Media\Alarm01.wav"
    
    $sound = New-Object System.Media.SoundPlayer;
    $sound.SoundLocation="$Play";
    $sound.Play()
}

Tabi bunların hepsi $profile dosyamın içindeki

  function profile {
  ...
  }

fonksiyonu içinde oluyor.