Powershell에서 Email 보내기


Send-MailMessage를 사용하여 자신의 상용 메일을 이용하여 상대방에게 이메일을 보낼 수 있다. 특히 아래와 같이 작업하여 mymessage.ps1을 만들어 보내면 쉽게 보낼 수 있다.

또한 Windows Server를 사용하여 smtp Server를 자신이 만들어서 사용한다면 불편하게 암호를 입력하지 않고도 쉽게 보낼 수 있다. 이렇게 하는 장점은 사용자가 로그온/로그오프 할 때 자동으로 이메일을 보낼 수 있다는 것이다.

1) Hotmail을 이용하여 SSL로 메시지 보내기

Send-MailMessage -From jesuswithme@hotmail.com -SmtpServer smtp.live.com -UseSsl $true -Port 587 -Credential (Get-Credential jesuswithme@hotmail.com) -To jesuswithme@gmail.com -Subject “This is my message from Powershell” -Body “How is it going?” -Attachments C:\temp\project.txt

** 이렇게 하면 Popup 창이 나타나는데 jesuswithme@hotmail.com의 자신의 password를 입력해야 한다

** .ps1 스크립틀 만들 때 Param()을 이용하면 To, Subject, Attachment등을 다양하게 입력하면서 이메일을 보낼 수 있다.

2) 로컬 SMTP Server를 이용하여 메일 보내기

Send-MailMessage -From jesuswithme@hotmail.com -SmtpServer localhost  -To jesuswithme@gmail.com -Subject “This is my message from Powershell” -Attachments C:\temp\project.txt

3) Param()을 이용하여 스크립트를 생성하여 메일 보내기

Param (
[Parameter(Mandatory=$True)]
$To,
[Parameter(Mandatory=$True)]
$Subject,
[Parameter(Mandatory=$True)]
$Body
)
Send-MailMessage -From jesuswithme@hotmail.com -SmtpServer localhost -To $To -Subject $Subject -Body $Body

** 이것을 SendMail.ps1 파일로 저장하여 실행하면 To:,  Subject:, $Body: 가 Popup이 되면 적절하게 입력하여 메일을 보낼 수 있다.

User Mailbox를 다른 Mailbox Database로 이동하기


  • 사용자의 사서함을 다른 서버의 Mailbox Database로 옮기고자 한다
  • 직원의 근무 부서를 옮기는 경우 그 직원이 근무하는 쪽에 있는 사서함 서버로 이동하는 것이 필요하다.
  • 한 사용자의 사서함을 옮기기 위해서는 다음과 같이 하면 된다.
    • 해당 Recipient를 선택한다
    • 마우스 우측 버튼을 클릭하여 [New Local Move Request]를 클릭한다.
    • [Target Mailbox Database] Browse를 클릭하여 이동하고자 하는 Mailbox Database를 선택한다
    • 이렇게 하면 사용자 사서함이 다른 곳으로 이동된다
  • 이것을 [Exchange Management Shell]을 사용하면 다음과 같이 하면 된다.
    • Get-Mailbox -Identity wei | New-MoveRequest -TargetDatabase “Accounting”
  • 만약 특정한 Mailbox Database에 저장된 모든 사용자 사서함을 몽땅 다른 Mailbox Database로 옮기고자 할 때는 다음과 같이 하면 
    된다.
    • 새로운 Mailbox Database를 생성한다.(MBX1) 이것은 옮길 Database이다.
    • Get-Mailbox -Database “Accounting” | New-MoveRequest -TargetDatabase “MBX1”


스크립트에서 사용하는 Param()의 다양한 사용법


  • Powershell script 를 사용할 때 스크립트 내에 Param()을 사용하면 참 편리하다. 이것은 스크립트에 매개변수(Parameter)를 사용하는 것을 말한다.
  • , 사용자가 생성한 스크립트에도 사용자가 원하는 Parameter를 생성하여 사용할 수 있다는 것이다.
  • 다음은 다양한 방법으로 Param()을 사용하는 예이다.
    • Param (
      $ComputerName
      )

    • Param (
      $ComputerName = “localhost”
      )
      ** 매개 변수를 입력하지 않았을  Default 값을 지정한 것이다
       
    • Param (
      $ComputerName,
      $Item
      )
      ** 여러 개의 매개변수를 사용할 때는 comma로 구분해 준다
       
    • Param (
      [Parameter(Mandatory=$true)]
      $ComputerName
      )
      ** 관리자가 매개변수 값을 모르더라도 강제적으로 입력하라고 화면에 보여준다
       
    • Param (
      [Parameter(Mandatory=$true)]
      $ComputerName,
      [Parameter(Mandatory=$true)]
      $Item
      )
      ** 매개변수가 여러 개일 경우에는 각각에 모두 [Parameter(Mandatory=$true)] 작업을 해준다

    • Param (
      $ComputerName = (Read-Host -Prompt “Enter your computer name”)
      )
      ** 화면에 어떻게 입력할 것인지를 정확하게 알려주고 싶을 때 사용한다
              
    • Param (
      $ComputerName= (Read-Host -Prompt “Enter your computer name”),
      $Item = (Read-Host -Prompt “Type your item to see”)
      )

    • Param (
      [string]$ComputerName = “localhost”,
      [int]$Newest = 5
      )

      ** 입력하는 값의 데이터 형식을 지정해준다. 이렇게 하면 컴퓨터 이름을 입력하는 항목에 숫자를 사용하면 오류가 발생하게 된다.
  • 이제 스크립트 파일을 생성하여 테스트해 본다.
    • C:\pro.ps1 파일을 생성한다


    • 이제 한 번 테스트 해 본다



매개변수 -CompuerName 사용법


  • Get-Process, Get-Service 등등을 실행할  -ComputerName이라는 매개변수(Parameter)를 사용하게 된다. 이  -Computername을 사용하지 않으면 기본적으로 로컬 컴퓨터 이름이 입력된다.
  • 하지만 -ComputerName을 사용할 때는 그 뒤에 컴퓨터 이름을 반드시 사용해주어야 한다.
  • 그렇다면 컴퓨터 이름을 어떻게 사용하는지 알아본다. 다음과 같은 방법으로 사용된다.
    • 그냥 뒤에 컴퓨터 이름을 직접 입력하면 된다.
      Get-Process -ComputerName pc1, pc2

    • 컴퓨터 이름을 Text 파일에 입력된 것을 불러 와서 사용한다. 이렇게 하면 늘 검사하는 컴퓨터 이름을 입력되어 있기 때문에 사용하는데 추가로 입력할 필요가 없어서 편리하다.
      Get-Service -ComputerName (Get-Content c:\computers.txt)

    • 컴퓨터 이름을 어떤 cmdlet의 결과 값을 사용한다.
      Get-Hotfix -ComputerName (Get-ADComputer -Filter * | Select-Object -ExpandProperty name)
      Invoke-Command -ComputerName (Get-ADComputer -Filter {Name -like “nyc-svr*”} | Select-Object -ExpandProperty name) -ScriptBlock {ipconfig}

      ** 여기서 Select-Object -ExpandProperty Name으로 하면 결과가 나오고,  Select-Object -Property Name으로 하면 결과가 나오지 않으니 주의한다.  그 이유는 아래의 그림을 보면
      알 수 있다.


      ** Select-Object -Property를 사용하면, 값만 나오는 것이 아니라 부가적인 정보나오기 때문에 문제가 되는 것이다. 우리가 원하는 것은 (컴퓨터 이름)만 나와야지 다음 단계를 처리할 수 있기 때문에 Select-Object -ExpandProperty를 사용해야 하는 것이다.
      ** 여기서 우리는 Select-Object에서 사용 가능한 매개변수인 -Property -ExpandProperty의 차이점을 알 필요가 있다.

      ** 특히 여러 개의 컴퓨터 이름을 이용할 , 즉 Active Directory에 있는 컴퓨터 이름을 활용하는 이 형식을 알아 두면 참 편리하다. 꼭 기억해 두기를…
      Get-Hotfix -ComputerName (Get-ADComputer -Filter * | Select-Object -ExpandProperty name)
       

      • 컴퓨터 이름을 파이프라인의 입력 값 중에서 특정한 속성 값을 사용한다.
        Get-ADComputer -Filter * | ForEach-Object {Invoke-Command -ComputerName $_.DnsHostname-ScriptBlock {gpupdate.exe /force}}
        Get-ADComputer -Filter * | ForEach-Object {Invoke-Command -ComputerName $_.Name -ScriptBlock {mkdir c:\powershell}}
        ** -computername $_.Name도 되고 -computername $_.DnsHostName도 모두 가능하다. , Get-ADComputer -Filter *에서 나온 결과를 보면 DnsHostName nyc-svr1.contoso.com이고 Name nyc-svr1이기 때문에 결과를 도출하는데는 아무 문제가 없다.
        ** c.번과 d.번의 결과는 동일한 것임을 알 수 있다. , C.번 형식으로 하나 D.번 형식으로 하나 동일한 표현이라는 것이다.

서버 관리자가 모든 AD 구성원 컴퓨터들로 하여금 Gpupdate.exe를 실행하도록 하자


  • 중앙에서 Group Policy를 변경하고 모든 클라이언트가 5분내로 모두 적용시키고자 한다. 이럴 때 회사 모든 직원들에게 알려주어서 수동으로 컴퓨터를 재시작하거나 gpupdate /force를 하라고 부탁하는 것을 현실적으로 무리가 된다.
  • 그래서 중앙에서 Powershell cmdlet를 사용하여 서버 관리자가 모든 AD 구성원 컴퓨터들에게 gpupdate /force를 내릴 수 있다
  • 서버 관리자는 자신의 컴퓨터에서 powershell console을 열어서 AD에 있는 구성원 컴퓨터의 목록을 이용하여 Windows Remote Management 기술을 이용하여(포트 번호 5985) 원격에서 명령어 실행할 수 있다.
  • 다음과 같이 진행하여 된다.
    • 먼저 DC에서 GPO_imsi라는 새로운 Group Policy를 만든다. 그 내용은 스크립트를 다운로드하여 실행하도록 한다. 이 스크립트 안의 내용은 적당히 알아서 만들면 된다. 예를 들면 Hotfix를 파일 서버에서 다운로드하여 설치하기
    • Powershell console 화면을 실행한다
    • Get-Adcomputer -Filter * | ForEach-Object {Invoke-Command -Computername $_.DnsHostname -Scriptblock {gpupdate.exe /force}}
      ** 여기서  computername에 Name 또는 DnsHostname을 모두 사용할 수 있다.
      ** | ForEach-Object {Invoke-Command -Computername $_.DnsHostname -Scriptblock {gpupdate.exe /force}} 를 알아두어야 한다.
      ** ForEach는 처리 속도면에서 좀 느리다. 좀 더 빨리 처리하기 위해서는 아래와 같이 하면 좋다.

    • Invoke-Command -ComputerName (Get-ADComputer -Filter * | Select-Object -ExpandProperty Name) {gpupdate.exe /force}
    • 위의 두 명령어에 대하여 앞에 Measure-Command {   }을 해서 TotalMilliseconds를 보면 처리 속도를 확인할 수 있다.
    • 이렇게 하여 관리자는 클라이언트 컴퓨터에 새로운 Group Policy가 적용되었는지 확인하면 된다.
    • 정말로 대단한 것이다. 이렇게 하면 중앙에서 모든 컴퓨터 앞에서 직접 작업하는 것 처럼 할 수 있다는 것이다. 그것도 한 대가 아니라 수십 대의 컴퓨터를 동시에 작업을 할 수 있다는 말이다.
    • 다음과 같이 명령을 진행해 본다.
      • Get-Adcomputer -Filter {name -like “*Cluster*”}
      • Get-Adcomputer -Filter {name -like “*Cluster*”} | ForEach-Object {Invoke-Command -Computername $_.DnsHostname -Scriptblock {ipconfig}}
      • Get-Adcomputer -Filter {name -like “*Cluster*”} | ForEach-Object {Invoke-Command -Computername $_.DnsHostname -Scriptblock {ping lon-dc1}}
        ** 이렇게 하면 수 십대의 컴퓨터가 한 컴퓨터(lon-dc1)로 Ping을 실행하게 된다

Powershell Script를 이용하여 Active Directory 사용자 계정을 쉽게 생성하기


  • Active Directory 사용자 계정을 만드는 방법은 다양한다. [Active Directory 사용자  컴퓨터], [Active Directory 관리 센터], [net users 명령어], [Powershell]등을 사용할  있다.
  • Powershell을 이용하여 사용자 계정을 생성하면 처음에는 복잡하지만 조금만 익숙해지면 훨씬 편리하다. 특히 수십/수백개의 계정을 동시에 만들 때 참으로 편리하고(csv 파일 이용) 또는 Powershell Script를 이용하여 금방 만들 수 있다여기서는 확장자 .ps1을 갖는 Powershell Script를 이용하여 Active Directory 사용자 계정을 생성해보고자 한다.
  • 다음과 같이 진행하여 사용자 계정을 생성한다.
    • 관리 도구에서 [Active Directory Module for Windows Powershell]을 실행한다여기서는 AD와 관련된 cmdlet를 사용할 수 있기 때문이다.
    • 아래의 내용처럼 스크립트(C:\users.ps1를 생성한다.)
      Param (
      $FullName = (Read-Host -Prompt “직원들의 이름을 입력하세요. Ex) 이용식, Yongshik Lee”),

      $LogonID = (Read-Host -Prompt “로그온 ID를 입력하세요. Ex) jesuswithme”)

    • )
      New-ADUser -Name $FullName
      -SamAccountName $LogonID -AccountPassword (ConvertTo-SecureString -String “Pa$$w0rd” -AsPlainText -Force) -Enabled $true
      ** 어떻게 입력하는지 방법을 알려주기 위해서  $FullName = (Read-Host -Prompt “직원들의 이름을 입력하세요. Ex) 이용식, Yongshik Lee”)으로 사용한다

       

    • 이제는 Script 실행할 환경이 되어 있는지 확인하고, 혹시 안되어 있으면 환경 설정을 한다.
      Get-ExecutionPolicy
       
    • 최종적으로 C:\Users.ps1 파일을 실행하여 직원들의 사용자 계정을 생성한다.
    • 사용자를 생성한 후 생성된 것을 확인하다.
      Get-ADUser -Identity jesuswithme
       

       


Powershell을 사용하여 AD에서 사용자 계정을 생성할 때 Read-Host -Prompt “Enter Your Password” -AsSecureString와 ConvertTo-SecureString “Pa$$w0rd” -AsPlainText -Force의 차이점은


Read-Host -AsSecureString과 ConverTo-SecureString “Pa$$w0rd” -AsPlainText -Force의 차이점

Powershell을 가지고 AD에 하나의 사용자 계정을 생성할 때는 보통 다음과 같이 한다.

New-ADUser -Name “Yongshik Lee” -SamAccountName “jesuswithme” -AccountPassword (Read-Host -Prompt “Enter Your Password” -AsSecureString) -Enabled $true

New-ADUser -Name “Yongshik Lee” -SamAccountName “jesuswithme” -AccountPassword (ConvertTo-SecureString -String “Pa$$w0rd” -AsPlainText -Force) -Enabled $true

이 두문장의 차이는 무엇인가?
이것은 net users jesuswithme * /add /domain과 net users jesuswithme Pa$$word /add /domain과 비슷한 것이다.

즉, 앞의 것은 사용자 계정을 생성할 때 다른 사람이 암호를 못보도록 하는 것이고,
뒤의 것은 사용자 계정을 생성할 때 본인만이 있는 경우에 암호를 직접 입력하는 경우이다.

하지만 Powershell cmdlet는 암호 저장을 Secure String(문자열 암호를 볼 수 없음)으로 하는 것이고 net users는 plain string(문자열 암호를 볼 수 있음)으로 암호를 저장하는 것이다. 그래서 powershell을 사용하는 것이 보안성이 높다.

** 참고: -AsPlainText와 -Force는 반드시 쌍으로 사용하여야 한다. -Force가 빠지면 오류가 난다

또는 csv 파일을 이용하여 여러 개를 한꺼번에 만들 때도 이것을 사용할 수 있다.
Import-Csv C:\users.csv | New-ADUser

Get-AdUser -Filter {name -like “aduser*”} | Set-ADAccountPassword -Reset –NewPassword (Read-Host -Prompt “Enter Your Password” -AsSecureString)

Import-Csv C:\users.csv | New-ADUser
Get-AdUser -Filter {name -like “aduser*”} | Set-ADAccountPassword -Reset –NewPassword (ConvertTo-SecureString -String “Pa$$w0rd” -AsPlainText -Force)

Get-AdUser -Filter {name -like “aduser*”} | Enable-ADAccount