# 钉钉消息发送
$ErrorActionPreference = 'Stop'
# 钉钉消息推送相关
class DingMessage {
[string] $secret = ""
[string] $ServerUrl = ""
[void] send($title, $message) {
$server = $this.getServerUrl();
$this.sendContent($server, $title, $message)
}
# 返回服务器地址,根据需要进行签名
[string]getServerUrl() {
if (-not $this.ServerUrl) {
throw [System.ArgumentException]::new("ServerUrl is null")
}
$server = $this.ServerUrl
if ($this.secret) {
$server = $this.signUrl($server, $this.secret)
}
return $server
}
# 签名
[string] signUrl([string]$server, [string]$secret) {
$timestamp = [DateTimeOffset]::Now.ToUnixTimeMilliseconds() # 获取当前时间戳(毫秒)
$stringToSign = "$timestamp`n$secret" # 构建待签名字符串
# 创建 HmacSHA256 实例并设置密钥
$hmac = New-Object System.Security.Cryptography.HMACSHA256
$hmac.Key = [System.Text.Encoding]::UTF8.GetBytes($secret)
$signData = $hmac.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($stringToSign)) # 计算签名
$base64Sign = [System.Convert]::ToBase64String($signData) # Base64 编码
$urlEncodedSign = [uri]::EscapeDataString($base64Sign) # URL 编码
return "$server×tamp=$timestamp&sign=$urlEncodedSign"
}
# 发送消息
[void] sendContent([string]$server, [string]$title, [string]$message) {
[PSCustomObject]$body = $this.buildContent($title, $message)
$jsonBody = $body | ConvertTo-Json -Depth 10 -Compress
$bytes = [System.Text.Encoding]::UTF8.GetBytes($jsonBody)
$response = Invoke-WebRequest -Uri $server -Method Post -Body $bytes -ContentType "application/json" -UseBasicParsing
$this.verifyResponse($response)
}
[PSCustomObject]buildContent([string]$title, [string]$message) {
return [PSCustomObject]@{
msgtype = "markdown"
markdown = [PSCustomObject]@{
title = $title
text = $message
}
}
}
# 解析 Invoke-WebRequest 返回结果
[void]verifyResponse(<# [Microsoft.PowerShell.Commands.BasicHtmlWebResponseObject] 有些机器上没有这个类型 #> $response) {
if ($response.StatusCode -ne 200) {
throw [ApplicationException]::new("Failed to send message, [$($response.StatusCode)], $($response.StatusDescription)")
}
$json = $response.Content | ConvertFrom-Json
if ($json.errcode -ne 0) {
throw [System.ApplicationException]::new("Failed to send message, [$($json.errcode)], $($json.errmsg)")
}
}
static [string] buildMarkdownMessage([string]$title, [string[]]$messages) {
$markdown = @()
$markdown += "### $title"
foreach ($message in $messages) {
$markdown += "- $message"
}
return [string]::Join("`n", $markdown)
}
static [DingMessage] createDefault() {
$message = [DingMessage]::new()
$message.secret = "xxxxx"
$message.ServerUrl = "https://oapi.dingtalk.com/robot/send?access_token=xxxx"
return $message
}
}
try {
$title = "备份完成"
$content = [DingMessage]::buildMarkdownMessage($title, @("备份时间:$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')", "备份机器:$([System.Environment]::MachineName)", "备份结果:成功"))
$message =[DingMessage]::createDefault()
$message.send($title, $content)
}
catch {
Write-Error "Error: $($_.Exception.Message)"
throw $_.Exception
}