RedPlug's Tory

 

PS C:\Windows\system32> Install-Module PSSlack -Force
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\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:7405 char:21
+ ...     $null = PackageManagement\Install-PackageProvider -Name $script:N ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (Microsoft.Power...PackageProvider:InstallPackageProvider) [Install-PackageProvider], Exception
    + FullyQualifiedErrorId : NoMatchFoundForProvider,Microsoft.PowerShell.PackageManagement.Cmdlets.InstallPackageProvider
 
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:7411 char:21
+ ...     $null = PackageManagement\Import-PackageProvider -Name $script:Nu ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (NuGet:String) [Import-PackageProvider], Exception
    + FullyQualifiedErrorId : NoMatchFoundForCriteria,Microsoft.PowerShell.PackageManagement.Cmdlets.ImportPackageProvider
 
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:7415 char:30
+ ... tProvider = PackageManagement\Get-PackageProvider -Name $script:NuGet ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Microsoft.Power...PackageProvider:GetPackageProvider) [Get-PackageProvider], Exception
    + FullyQualifiedErrorId : UnknownProviderFromActivatedList,Microsoft.PowerShell.PackageManagement.Cmdlets.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 PSSlack -Force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Install-Module], InvalidOperationException
    + FullyQualifiedErrorId : CouldNotInstallNuGetProvider,Install-Module
    

PS C:\Windows\system32>  [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12


PS C:\Windows\system32>  Install-PackageProvider -Name NuGet

 

하기명령어 실행 후 설치 진행

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

Install-PackageProvider -Name NuGet

Esxi 상에서 테스트 목적으로 기존에 만들어져 있던 윈도우 VM을 켜서 테스트를 진행하는 도중 일정시간이 지나면 VM이 shutdown 되는 증상이 발견되었으며, 해당 증상에 대해서 확인을 해보니 한가지 특이점이 있었습니다.

한시간 마다 서버가 shutdown 되는 증상이었습니다.(...처음에 시간도 생각못해서 꺼지면 켜고 꺼지면 켜고 몇번 반복 했네요..)

확인 해본 사항으로는

esxi쪽 CPU/메모리 부족 : 특이사항 없음

누군가가 끈 흔적(로그 등) : 특이사항 없음

서버 내 스케쥴 : 특이사항 없음

그러던 와중 shutdown 시점에 eventlog에 뭔가 남아있는게 있나 싶어서 찾아봤는데

The process C:\Windows\system32\wlms\wlms.exe (XXXXX) has initiated the shutdown of computer XXXXX on behalf of user NT AUTHORITY\SYSTEM for the following reason: Other (Planned) Reason Code: 0x80000000

계획된 시스템 OFF...?

관련 해서 구글링을 진행하니 하기와 같은 내용을 찾을 수 있었습니다. (라이선스 만료되면 1시간 마다 꺼짐)

After Windows license expires, you will see a similar message as shown below and then VM will auto shutdown every hour.

...테스트 하고 있던 서버도 license Expired 문구가 떠있던 서버었던 터라 라이선스를 넣거나 막을 방법을 찾아야 했고

WLMS(Windows Licensing Monitoring Service)를 OFF시키면 된다는 내용을 확인 했고

하기와 같이 가이드 대로 진행하였습니다.

1. psExec Tools 다운로드 및 압축 해제 : https://learn.microsoft.com/en-us/sysinternals/downloads/psexec

2. 관리자 모드로 cmd 창오픈

3. psexec폴더로 이동 후 psexec -i -s cmd.exe

4. 새로 뜬 커맨드 창에 whoami로 system 계정 확인( WLSM off권한)

5. services.msc로 서비스 창 띄운 후  WLMS 서비스 disabled

6. 실행된 서비스를 멈출 수 없기 때문에 재부팅을 진행후에 실제로 서비스가 stop 되었는지 확인

7. 정상 작동 확인

실제로 상기 작업 진행 후 서버가 재부팅 되지 않음을 확인하였습니다.

새벽에 일어나서 한 시간마다 서버켜는 요상한 짓은 하지 않아도 되게 되었습니다.

다만 상기 방법은 정상인 방법은 아니기 때문에 실 환경에서는 사용하지 않고 테스트 환경에서 급하게 사용이 필요한 경우에 사용하시면 될 것 같습니다.

 

참고 링크

https://digitalitskills.com/how-to-stop-windows-server-auto-shutdown-every-hour-after-license-expire/

업무상 자격증명을 삭제 해야 하는 경우가 발생합니다.

매번 작업 해주기 귀찮아서 확인해보니 한번에 삭제 하는 방법이 있네요

....저걸 하나하나 모두 삭제

cmdkey로 리스트를 불러올 수 있어서 혹시나 해보았으나...될리가 없죠..

구글링을 해보니 누군가 간단하게 스크립트로 만들어 놓은 것을 확인

$Credentials = (cmdkey /list | Where-Object {$_ -like "*Target=*"})
Foreach ($Target in $Credentials) {
    $Target = ($Target -split (":", 2) | Select-Object -Skip 1).substring(1)
    $Argument = "/delete:" + $Target
    Start-Process Cmdkey -ArgumentList $Argument -NoNewWindow -RedirectStandardOutput $False
    }

cmdkey에서 리스트를 뽑아서 한땀한땀 삭제를 해주는 스크립트 입니다.

찾아서 파괴파괴!

돌리고 나니... 모두 삭제 확인하였습니다.

 

 

출처 : https://gist.github.com/janikvonrotz/7819990

redplug 입니다.

Windows Server에 인증키 값을 MAK -> KMS 변경이 필요한 경우에 사용하는 스크립트 입니다.

Azure VM 인 경우 Azure KMS사용을 위하여 $AzureKMSUser 활성

2012 R2의 경우 get-computerinfo 명령어가 없어 systeminfo 값을 활용하여 체크 합니다.

하기 기입된 KMS키는 MS Docs에 공개된 KMS용 Client키(KMS 인증을 받기 위해 적용하는 키) 입니다.

# kmscheck.ps1

kmscheck.zip
0.00MB

아래 코드를 긁어서 할 경우 정상적으로 불러오지 못하는 경우가 있어 첨부된 파일을 사용부탁드립니다.

 

 

# kmscheck.ps1
# Windows 2012, 2012 R2, 2016, 2019 KMS Key Change and activation Script
# Windows use on Auzre, AzureKMSUse setting 1
# KeyCheckMode is just check KMS Key Serial, not change key and activation
# Windows KMS Client key is public. url : https://docs.microsoft.com/ko-kr/windows-server/get-started/kms-client-activation-keys
 
# Options
$KeyCheckMode = 1 # 1=True, 0=False
$AuzreKMSUse = 1 # 1=True, 0=False
 
$WS2012Check_en = systeminfo | Select-String -pattern "OS Name:"
$WS2012Check_kr = systeminfo | Select-String -pattern "OS 이름:"
 
if ( $WS2012Check_en -eq $null) {
    $OSLang = "kr"
    $WS2012Check = $WS2012Check_kr
}
else {
    $OSLang = "en"
    $WS2012Check = $WS2012Check_en
}
 
if ( $WS2012Check -like "*Microsoft Windows Server 2012*") {    
    switch ( $OSLang ) {
        'en' {
            $OsName = $WS2012Check -creplace 'OS Name:'''
            
        }
        'kr' {
            $OsName = $WS2012Check -creplace 'OS 이름:'''
        }
    }
    $OsName = $OsName.TrimStart()
    
}
else {
    $OsName = (get-computerinfo).OsName
}
 
# Windows Version Edition Check
Write-Host "OSName : ", $OsName
switch ( $OsName ) {
    # Windows Server 2012
    'Microsoft Windows Server 2012' {
        $kmskey = "BN3D2-R7TKB-3YPBD-8DRP2-27GG4"
    }
    'Microsoft Windows Server 2012 Standard' {
        $kmskey = "XC9B7-NBPP2-83J2H-RHMBY-92BT4"
    }
    'Microsoft Windows Server 2012 Datacenter' {
        $kmskey = "48HP8-DN98B-MYWDG-T2DCC-8W83P"
    }
    # Windows Server 2012 R2
    'Microsoft Windows Server 2012 R2 Standard' {
        $kmskey = "D2N9P-3P6X9-2R39C-7RTCD-MDVJX"
    }
    'Microsoft Windows Server 2012 R2 Datacenter' {
        $kmskey = "W3GGN-FT8W3-Y4M27-J84CP-Q3VJ9"
    }
    'Microsoft Windows Server 2012 R2 Essentials' {
        $kmskey = "KNC87-3J2TX-XB4WP-VCPJV-M4FWM"
    }
    # Windows Server 2016
    'Microsoft Windows Server 2016 Datacenter' {
        $kmskey = "CB7KF-BWN84-R7R2Y-793K2-8XDDG"
    }
    'Microsoft Windows Server 2016 Standard' {
        $kmskey = "WC2BQ-8NRM3-FDDYY-2BFGV-KHKQY"
    }
    'Microsoft Windows Server 2016 Essentials' {
        $kmskey = "JCKRF-N37P4-C2D82-9YXRT-4M63B"
    }
    # Windows Server 2019
    'Microsoft Windows Server 2019 Datacenter' {
        $kmskey = "WMDGN-G9PQG-XVVXX-R3X43-63DFG"
    }
    'Microsoft Windows Server 2019 Standard' {
        $kmskey = "N69G4-B89J2-4G8F4-WWYCC-J464C"
    }
    'Microsoft Windows Server 2019 Essentials' {
        $kmskey = "WVDHN-86M7X-466P6-VHXV7-YY726"
    }
}
 
if ( $KeyCheckMode -eq 0 ) {
    if ( $AuzreKMSUse -eq 1 ) {
        write-host "### KMS Server Change (Azure)"
        Invoke-Expression "$env:windir\system32\cscript.exe $env:windir\system32\slmgr.vbs /skms kms.core.windows.net:1688"
    }
 
    write-host "### Insert KMS Key"
    Invoke-Expression "$env:windir\system32\cscript.exe $env:windir\system32\slmgr.vbs /ipk $kmskey"
 
    write-host "### KMS Key Activation"
    sleep 10
    Invoke-Expression "$env:windir\system32\cscript.exe $env:windir\system32\slmgr.vbs /ato"
    Read-Host -Prompt "Press any key to continue"       
}
else {
    write-host ""
    write-host "#########################################################"
    write-host "###########           KEY CHECK MODE          ###########"
    write-host "########### KMS NOT ACTIVATE, JUST KEY CHECK  ###########"
    write-host "#########################################################"
    write-host "OSName  : " $OsName
    write-host "KMS Key : " $kmskey
}
 

redplug입니다.

ADFS(Active Directory Federation Services)의 웹페이지상에 하단에 Microsoft Copyright 부분이 있는데 해당 부분에 대한 삭제 정보는 하기와 같습니다.

https://docs.microsoft.com/ko-kr/windows-server/identity/ad-fs/operations/remove-the-microsoft-copyright

다만 삭제가 가능하고 수정은 불가능한ㄷ요

삭제가 아닌 수정을 하고자 하는 경우에는 하기와 같이 작업 합니다. 

adfs서버에서 테마 Export할 폴더 생성 -> Powershell 오픈

# 사용자 테마 생성
New-AdfsWebTheme –Name custom –SourceName default

# 폴더 지정하여 테마 Export
Export-AdfsWebTheme -Name custom -DirectoryPath C:\export

추출한 폴더 -> sciprt 폴더 -> onlolad.js 파일 오픈 후 최하단에 문구 추가후 저장.

document.getElementById('copyright').innerHTML='변경하고자 하는 copyright로 문구 수정'

 

# 설정한 테마 적용
Set-AdfsWebTheme -TargetName custom -OnLoadScriptPath "c:\export\script\onload.js"

웹페이지에서 수정 정보 확인

 

Wifi 기본 밴드위스 설정 및 로밍 주동성 변경 스크립트

그룹정책용으로 작성, 관리자 권한으로 실행 필요

Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Control\Class -Recurse -ErrorAction silentlyContinue | Get-ItemProperty |  

ForEach-Object {if ($_.RoamingPreferredBandType -ge 0) { 
$path = $_.pspath 

# 5GHz 밴드 기본 설정(0 = 기본 설정 없음, 1 = 2.4GHz 밴드 설정, 2 = 5GHz 밴드 기본 설정)
Set-ItemProperty $path -name "RoamingPreferredBandType" -Value "2"

# 로밍의 주동성 (0 ~ 4 : 최하 ~ 최고)
Set-ItemProperty $path -name "RoamAggressiveness" -Value "4" 

write-output $_.pspath 
} 
}

 

참고 : community.intel.com/t5/Wireless/Setting-Preferred-Band-to-5ghz/td-p/352146

[Powershell] 함수1

Windows2020. 11. 21. 21:46

요새 공부를 하고 있긴 한데 정작 파워쉘쪽에 좀 소홀 했던것 같아서 

오랜만에 김도균 강사님 책 펴고 공부해봤네요~^^

어떤 언어를 해도 함수얘기는 거의 공통적으로 나오는 얘기라서 어렵지 않게 이해가 된 것 같습니다.

실무에서 바로 쓰는 파워쉘 - 김도균
9장 - 고급 스크립트 작성 기술

단순한 스크립트 작성에서 좀 더 나아가기 위한 방법인 함수에 대한 내용입니다.

함수의 기본 골격은 다음과 같습니다.

Function Verb-Noun {

     [CmdletBinding()]

     1) param()

     2) BEGIN{}

     3) PROCESS{}

     4) END{}

}

1. param

[Parameter(위치, 필수 매개변수, 파이프라인 입력)]

[데이터 형식]$변수명 = 기본값(옵션)

2. BEGIN

제일먼서 실행되는 부분이며 한번만 실행된다. 사전설정이 필요한 구문을 작성 예) 데이터베이스 초기 연결 설정, 특별한 설정이 필요 없는 경우 비워 놓는다.

3. PROCESS{}

함수의 주 로직이 들어가는 부분, 반복 처리를 하는 로직의 경우 작성 시 BEGIN쪽으로 넣어야 하는 블록을 구분하는게 좋다.(한번 실행하는걸 여러번 실행하게 되기 때문)

4. END{}

제일마지막에 실행되는 구분. 정리 작업에 해당 하는 구문(데이터베이스 연결종료 등), 별도로 필요하지 않는 다면 비워놓는다.

 

함수를 만드는 절차

  1. 함수를 function이라는 키워드와 함께 동사-명사 이름 규칙을 따라 함수 이름을 선언
  2. 함수의 블록 내부에서 처리하는 매개변수 설정을 param() 블록에 입력
  3.  주 처리 로직의 설정에 해당하는 구문을 BEGIN 블록에 입력
  4. 원하는 작업의 주 처리 로직을 PROCESS 블록에 입력
  5. 주 처리 로직의 정리에 해당 하는 작업을 END 블록에 입력

예제함수

function Get-SecurityEvents {
[CmdletBinding()]
Param(
[Parameter(Position=0,Mandatory=$True)]
[string]$ComputerName,

[int]$EventID = 4634
)   
    BEGIN 
    {
        $LogName = Read-Host "로그 이름을 입력하세요."        
    }
    PROCESS
    {
        Get-EventLog -ComputerName $ComputerName `
        -LogName $LogName |
    Where-Object -Property EventID -eq $EventID |
    Select-Object -First 7
    }
END {}
}

함수로 만들경우 바로 실행되지 않으며 함수를 실행하여 메모리에 올리고 실행하고자 하는 함수 이름을 콘솔에서 호출하여야 한다.

하기는 함수를 호출 후 확인하는 스크린샷

정상적으로 함수 호출 되었으며, 실행

파워쉘의 범위

범위 설명 범위 한정자
전역 파워셸 세션을 시작할 때 범위 $global:변수명
로컬 현재 범위, 전역 범위나 다른 범위가 될 수 있다. $local:변수명
스크립트 스크립트 파일이 실행되는 동안 만들어지는 범위 $script:변수명
전용(Private) 전용 범위의 항목은 현재 범위 외부에서 보이지 않는다 $private:변수명
숫자를 부여한 범위 숫자 범위는 한 범위와 다른 범위의 상대 위치를 나타낸다.  

범위 한정자를 활용하면 함수나 스크립트 내부의 변수에 접근하게 하거나, 함수의 실행 범위를 지정해 다른 범위에서 해당 함수를 접근하게 할 수 있다.

예제(Chap9EX2~3.ps1)

$Global:globalVar='전역 범위. 스크립트 밖에서 접근'

Function Check-FunctionScope
{
    $functionVar = '함수 범위. 함수내에서만 접근'
    "functionVar은 $functionVar"
    $Local:localVarInFunc='함수내에서 선언한 로컬 범위'
    $Script:scriptVarInFunc='함수내에서 선언한 스크립트 범위'
    $Global:globalVarInFunc='함수내에서 선언한 전역 범위'
    ''
    CallFrom-Function
}
''

$scriptVar = '스크립트 범위. 스크립트 내에서만 접근'
"scriptVar은 $scriptVar"
''

Check-FunctionScope
''
CallFrom-ScriptFunction global:CallFrom-Function
{
    $callByFunction = '다른 함수에서 불렀어요.'
    "callByFunction 변수는 $callByFunction"
}

Function global:CallFrom-Script
{
    $callByScript = '다른 스크립트에서 불렀어요.'
    "callByScript 변수는 $callByScript"
}

$Global:globalVar='전역 범위. 스크립트 밖에서 접근'

Function Check-FunctionScope
{
    $functionVar = '함수 범위. 함수내에서만 접근'
    "functionVar은 $functionVar"
    $Local:localVarInFunc='함수내에서 선언한 로컬 범위'
    $Script:scriptVarInFunc='함수내에서 선언한 스크립트 범위'
    $Global:globalVarInFunc='함수내에서 선언한 전역 범위'
    ''
    CallFrom-Function
}
''

$scriptVar = '스크립트 범위. 스크립트 내에서만 접근'
"scriptVar은 $scriptVar"
''

Check-FunctionScope
''
CallFrom-Script

3번스크립트 실행 후 2번 스크립트 실행

 

예제 : Chap9EX4.ps1

function Send-OutlookMail{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$False)]
        [string] $From = "redplug@outlook.com"
        [Parameter(Mandatory=$True)]
        [string] $To,
        [Parameter(Mandatory=$False)]
        [string] $Cc = "redplug@gmail.com"
        [Parameter(Mandatory=$True)]
        [string] $Subject,
        [Parameter(Mandatory=$False)]
        [string] $Body = "PowerShell Send Mail"
    )
    BEGIN 
    {
        $Cred = (Get-Credential)  // 인증처리 부분
        $SmtpSvr="smtp.live.com" 
        $SmtpPort="587"     
    }
    PROCESS
    {
        Send-MailMessage -From $From -To $To -Cc $Cc -Subject $Subject `
        -Body $Body -SmtpServer $SmtpSvr  -Port $SmtpPort -UseSsl `
        -Credential $Cred -Encoding UTF8
    }
    END
    {
        Clear-Variable -Name Cred
    }
}

발송엔 성공했는데 안보이길래 뒤져봤더니 스펨함에 떨어졌네요.

대상서버 TCP 389 Port Open 필요

1. RSAT 설치

2. runas /u:redplug\admin /netonly "mmc %windir%\system32\dsa.msc /server=IP or DNS"

패스워드 입력

dir /b /s > list.txt

/b : 가장 우측 정보만 노출

/s : 서브 디렉토리까지 포함하여 노출

> list.txt : 텍스트 파일로 추출

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters\AutoShareServer

 

REG_DWORD : 0

 

reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters /v AutoShareServer /t REG_DWORD /d 0x00000000 /f

 

출처 : https://support.microsoft.com/ko-kr/help/954422/how-to-remove-administrative-shares-in-windows-server-2008