[玩转系统] 周五乐趣:PowerShell 难题
作者:精品下载站 日期:2024-12-14 07:38:58 浏览:13 分类:玩电脑
周五乐趣:PowerShell 难题
这不会取代我的日历和任务列表,但它让我可以直接从 PowerShell 中查看我不想错过的事件。当我研究这个想法时,我最终得到了一个 PowerShell 模块 MyTickle.psm1,它有许多用于管理痒痒事件的函数,正如我所说的那样。我可以从 PowerShell 获取事件、添加、设置和删除。我认为该模块会成为一个很好的星期五有趣的帖子,因为它当然不是一个高影响力的项目,但它提供了一些关于构建模块和功能的想法,我希望您会发现这些想法有用。
现在的模块是一个文件。这是文件,下面我将讨论。
#requires -version 3.0
# ****************************************************************
# * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
# * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK. IF *
# * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, *
# * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING. *
# ****************************************************************
#MYTICKLE.PSM1
#Last updated 5/17/2013
#region Define module variables
#This should be the WindowsPowerShell folder under your Documents folder
$profileDir = Split-Path $profile
#the path to the tickle csv file
$TicklePath = Join-Path -Path $profileDir -ChildPath "mytickler.csv"
#the default number of days to display
$TickleDefaultDays = 7
#endregion
#region Define module functions
Function Get-TickleEvent {
<#
.Synopsis
Get Tickle Events
.Description
Get tickle events by id or name. The default behavior is to get all events in
date order. You can specify a range of ID numbers and use wildcards with the
event names. Use the Expired switch to get all tickle events that have already
occurred.
The command will not throw an exception if no matching tickle events are found.
#>
[cmdletbinding(DefaultParameterSetname="ALL")]
Param(
[Parameter(Position=0,ParameterSetName="ID")]
[int[]]$Id,
[Parameter(Position=0,ParameterSetName="Name")]
[string]$Name,
[Parameter(Position=0,ParameterSetName="Expired")]
[switch]$Expired,
[ValidateScript({Test-Path $_} )]
[string]$Path=$TicklePath
)
Write-Verbose "Importing events from $Path"
Switch ($pscmdlet.ParameterSetName) {
"ID" {
Write-Verbose "by ID"
$filter = [scriptblock]::Create("`$_.id -in `$id") }
"Name" {
Write-Verbose "by Name"
$filter = [scriptblock]::Create("`$_.Event -like `$Name") }
"Expired" {
Write-Verbose "by Expiration"
$filter = [scriptblock]::Create("`$_.Date -lt (Get-Date)") }
"All" {
Write-Verbose "All"
$filter = [scriptblock]::Create("`$_ -match '\w+'") }
}
#import CSV and cast properties to correct type
Import-CSV -Path $Path |
Select @{Name="ID";Expression={[int]$_.ID}},
@{Name="Date";Expression={[datetime]$_.Date}},
Event,Comment | where $Filter | Sort date
} #Get-TickleEvent
Function Set-TickleEvent {
<#
.Synopsis
Set a tickle event
.Description
This command will update the settings for a tickle event. You can update the
event name, date or comment. The easiest way to use this is to pipe an tickle
event to this command.
#>
[cmdletbinding(SupportsShouldProcess,DefaultParameterSetName="Inputobject")]
Param(
[Parameter(Position=0,Mandatory,HelpMessage="Enter the tickle event id",ParameterSetName="ID")]
[int]$Id,
[Parameter(Position=1,ValueFromPipeline,ParameterSetname="Inputobject")]
[object]$Inputobject,
[datetime]$Date,
[string]$Event,
[string]$Comment,
[ValidateScript({Test-Path $_} )]
[string]$Path=$TicklePath,
[switch]$Passthru
)
Begin {
write-verbose "Using $($PSCmdlet.ParameterSetName) parameter set"
}
Process {
#if ID only then get event from CSV
Switch ($pscmdlet.ParameterSetName) {
"ID" {
Write-Verbose "Getting tickle event id $ID"
$myevent = Get-TickleEvent -id $id
}
"Inputobject" {
Write-Verbose "Modifying inputobject"
$myevent = $Inputobject
}
} #switch
#verify we have an event to work with
if ($myevent) {
#modify the tickle event object
write-verbose ($myevent | out-string)
if ($Date) {
Write-Verbose "Setting date to $date"
$myevent.date = $Date
}
if ($Event) {
Write-Verbose "Setting event to $event"
$myevent.event = $Event
}
if ($comment) {
Write-verbose "Setting comment to $comment"
$myevent.comment = $comment
}
write-verbose "Revised: $($myevent | out-string)"
#find all lines in the CSV except the matching event
$otherevents = get-content -path $Path | where {$_ -notmatch "^""$($myevent.id)"}
#remove it
$otherevents | Out-File -FilePath $Path -Encoding ascii
#append the revised event to the csv file
$myevent | Export-Csv -Path $Path -Encoding ASCII -Append -NoTypeInformation
if ($passthru) {
$myevent
}
}
else {
Write-Warning "Failed to find a valid tickle event"
}
} #process
} #Set-TickleEvent
Function Add-TickleEvent {
<#
.Synopsis
Add a tickle event
.Description
This command will create a new tickle event. If the CSV file referenced by the
TicklePath variable does not exist, it will be created. You must enter an event
name and date.
#>
[cmdletbinding(SupportsShouldProcess)]
Param (
[Parameter(Position=0,ValueFromPipelineByPropertyName,Mandatory,HelpMessage="Enter the name of the event")]
[string]$Event,
[Parameter(Position=1,ValueFromPipelineByPropertyName,Mandatory,HelpMessage="Enter the datetime for the event")]
[datetime]$Date,
[Parameter(Position=2,ValueFromPipelineByPropertyName)]
[string]$Comment,
[ValidateNotNullorEmpty()]
[string]$Path=$TicklePath,
[switch]$Passthru
)
Begin {
#verify the path and create the file if not found
if (! (Test-Path $Path)) {
Write-Verbose "Creating a new file: $Path"
Try {
'"id","Date","Event","Comment"' |
Out-File -FilePath $Path -Encoding ascii -ErrorAction Stop
}
Catch {
Write-Warning "Failed to create $Path"
Write-Warning $_.Exception.Message
$NoFile = $True
}
}
}
Process {
if ($NoFile) {
Write-Verbose "No CSV file found."
#bail out of the command
Return
}
#get last id and add 1 to it
[int]$last = Import-Csv -Path $Path |
Sort {$_.id -AS [int]} | Select -last 1 -expand id
[int]$id = $last+1
$hash=[ordered]@{
ID = $id
Date = $date
Event = $event
Comment = $comment
}
Write-Verbose "Adding new event"
Write-Verbose ($hash | out-string)
$myevent = [pscustomobject]$hash
$myevent | Export-Csv -Path $Path -Append -Encoding ASCII -NoTypeInformation
if ($passthru) {
$myevent
}
} #process
} #Add-TickleEvent
Function Remove-TickleEvent {
<#
.Synopsis
Remove a tickle event
.Description
Remove one or more events from the tickle file. This will overwrite the current
file so you might want to back it up first with Backup-TickleFile.
.Example
PS C:\> get-ticklevent -expired | remove-tickleevent
#>
[cmdletbinding(SupportsShouldProcess,DefaultParameterSetName="Inputobject")]
Param(
[Parameter(Position=0,Mandatory,HelpMessage="Enter the tickle event id",ParameterSetName="ID")]
[int]$Id,
[Parameter(Position=1,ValueFromPipeline,ParameterSetname="Inputobject")]
[object]$Inputobject,
[ValidateScript({Test-Path $_} )]
[string]$Path=$TicklePath
)
Process {
#if ID only then get event from CSV
Switch ($pscmdlet.ParameterSetName) {
"ID" {
Write-Verbose "Getting tickle event id $ID"
$myevent = Get-TickleEvent -id $id
}
"Inputobject" {
Write-Verbose "Identifying inputobject"
$myevent = $Inputobject
}
} #switch
#verify we have an event to work with
if ($myevent) {
Write-Verbose "Removing event"
Write-Verbose ($myEvent | Out-String)
if ($pscmdlet.ShouldProcess(($myEvent | Out-String))) {
#find all lines in the CSV except the matching event
$otherevents = Get-Content -path $Path | where {$_ -notmatch "^""$($myevent.id)"}
#remove it
$otherevents | Out-File -FilePath $Path -Encoding ascii
}
} #if myevent
} #process
} #Remove-TickleEvent
Function Show-TickleEvent {
<#
.Synopsis
Display Tickle events in the console
.Description
This command gets upcoming tickle events and writes them to the console using
Write-Host. Use this command in your PowerShell profile script.
#>
[cmdletbinding()]
Param(
[Parameter(Position=0)]
[ValidateScript({Test-Path $_})]
[string]$Path=$TicklePath,
[Parameter(Position=1)]
[ValidateScript({$_ -ge 1})]
[int]$Days = $TickleDefaultDays
)
#import events from CSV file
$events = Import-Csv -Path $Path
#get upcoming events within 7 days sorted by date
$upcoming = $events |
where {
#get the timespan between today and the event date
$ts = (New-TimeSpan -Start (Get-Date) -end $_.Date).TotalHours
#find events less than the default days value and greater than 0
Write-Verbose $ts
$ts -le ($Days*24) -AND $ts -gt 0
} |
Add-Member -MemberType ScriptProperty -Name Countdown -value {New-TimeSpan -start (Get-Date) -end $this.date} -PassThru -force|
sort CountDown
if ($upcoming) {
#how wide should the box be?
#get the length of the longest line
$l = 0
foreach ($item in $upcoming) {
#turn countdown into a string without the milliseconds
$count = $item.countdown.ToString()
$time = $count.Substring(0,$count.lastindexof("."))
#add the time as a new property
$item | Add-Member -MemberType Noteproperty -name Time -Value $time
$a = "$($item.event) $($item.Date) [$time]".length
if ($a -gt $l) {$l = $a}
$b = $item.comment.Length
if ($b -gt $l) {$l = $b}
}
[int]$width = $l+5
$header="* Reminders $((Get-Date).ToShortDateString())"
#display events
Write-Host "`r"
Write-host "$($header.padright($width,"*"))" -ForegroundColor Cyan
Write-Host "*$(' '*($width-2))*" -ForegroundColor Cyan
foreach ($event in $upcoming) {
if ($event.countdown.totalhours -le 24) {
$color = "Red"
}
elseif ($event.countdown.totalhours -le 48) {
$color = "Yellow"
}
else {
$color = "Green"
}
#define the message string
$line1 = "* $($event.event) $($event.Date) [$($event.time)]"
if ($event.comment -match "\w+") {
$line2 = "* $($event.Comment)"
$line3 = "*"
}
else {
$line2 = "*"
$line3 = $null
}
$msg = @"
$($line1.padRight($width-1))*
$($line2.padright($width-1))*
"@
if ($line3) {
#if there was a comment add a third line that is blank
$msg+="`n$($line3.padright($width-1))*"
}
Write-Host $msg -ForegroundColor $color
} #foreach
Write-host ("*"*$width) -ForegroundColor Cyan
Write-Host "`r"
} #if upcoming events found
else {
$msg = @"
**********************
* No event reminders *
**********************
"@
Write-host $msg -foregroundcolor Green
}
} #Show-TickleEvent
Function Backup-TickleFile {
<#
.Synopsis
Create a backup of the tickle file
.Description
This command will create a backup copy of the tickle CSV file. The default path
is the same directory as the tickle file. You might want to backup the tickle
file before removing any events.
#>
[cmdletbinding(SupportsShouldProcess)]
Param(
[ValidateScript({Test-Path $_} )]
[string]$Path=$TicklePath,
[ValidateScript({Test-Path $_} )]
[string]$Destination = (Split-Path $TicklePath),
[switch]$Passthru
)
Try {
$ticklefile = Get-Item -Path $path
$backup = Join-Path -path $Destination -ChildPath "$($ticklefile.basename).bak"
Write-Verbose "Copying $path to $backup"
$ticklefile | Copy-Item -Destination $backup -ErrorAction Stop -PassThru:$Passthru
}
Catch {
Write-Warning "Failed to backup file"
Write-Warning $_.exception.message
}
} #Backup-TickleFile
#endregion
#region Define module aliases
Set-Alias -Name gte -value Get-TickleEvent
Set-Alias -name ate -Value Add-TickleEvent
Set-Alias -name rte -Value Remove-TickleEvent
Set-Alias -name ste -Value Set-TickleEvent
Set-Alias -name shte -Value Show-TickleEvent
Set-Alias -name btf -Value Backup-Ticklefile
#endregion
Export-ModuleMember -Function * -Variable TicklePath,TickleDefaultDays -Alias *
您应该能够从 WordPress 插件复制代码并将其粘贴到本地脚本文件中。您可以随意命名它,只需记住使用 .psm1 文件扩展名即可。该模块使用一些 PowerShell 3.0 功能,例如有序哈希表,但您可以进行修改以使其在 PowerShell 2.0 中运行。从根本上来说,它应该在两个版本中都可以工作。
这些事件存储在一个 CSV 文件中,我使用模块变量 $TicklePath 引用该文件。默认文件是名为 mytickler.csv 的文件,该文件位于“文档”下的 WindowsPowerShell 文件夹中。该模块还定义了一个名为 $TickleDefaultDays 的变量,默认值为 7。这会向属于该范围内的事件显示事件。为了使用,我将这些行添加到我的 PowerShell 配置文件中。
import-module c:\scripts\mytickle.psm1
show-tickleevent
结果是,当我启动新的 PowerShell 会话时,我看到类似这样的内容(有关帮助更新的消息来自其他内容,因此请忽略):
这是它的工作原理。
Show-TickleEvent 函数从 CSV 文件导入未来 7 天内将发生的事件。每个对象还获得一个附加属性,即剩余时间的时间跨度对象。然后该函数解析事件信息并在事件周围构造一个“盒子”。
#how wide should the box be?
#get the length of the longest line
$l = 0
foreach ($item in $upcoming) {
#turn countdown into a string without the milliseconds
$count = $item.countdown.ToString()
$time = $count.Substring(0,$count.lastindexof("."))
#add the time as a new property
$item | Add-Member -MemberType Noteproperty -name Time -Value $time
$a = "$($item.event) $($item.Date) [$time]".length
if ($a -gt $l) {$l = $a}
$b = $item.comment.Length
if ($b -gt $l) {$l = $b}
}
[int]$width = $l+5
$header="* Reminders $((Get-Date).ToShortDateString())"
#display events
Write-Host "`r"
Write-Host "$($header.padright($width,"*"))" -ForegroundColor Cyan
Write-Host "*$(' '*($width-2))*" -ForegroundColor Cyan
#get upcoming events within 7 days sorted by date
$upcoming = $events |
where {
#get the timespan between today and the event date
$ts = (New-TimeSpan -Start (Get-Date) -end $_.Date).TotalHours
#find events less than the default days value and greater than 0
Write-Verbose $ts
$ts -le ($Days*24) -AND $ts -gt 0
} |
Add-Member -MemberType ScriptProperty -Name Countdown -value {New-TimeSpan -start (Get-Date) -end $this.date} -PassThru -force |
sort CountDown
我根据事件的迫近程度设置前景色,然后将每个事件写入控制台,并包裹在边框中。
#define the message string
$line1 = "* $($event.event) $($event.Date) [$($event.time)]"
if ($event.comment -match "\w+") {
$line2 = "* $($event.Comment)"
$line3 = "*"
}
else {
$line2 = "*"
$line3 = $null
}
$msg = @"
$($line1.padRight($width-1))*
$($line2.padright($width-1))*
"@
if ($line3) {
#if there was a comment add a third line that is blank
$msg+="`n$($line3.padright($width-1))*"
}
Write-Host $msg -ForegroundColor $color
我特意使用 Write-Host,以便可以对事件进行颜色编码,并且因为我不希望配置文件向管道写入任何内容。由于该模块是在 PowerShell 会话开始时加载的,因此我始终可以运行 Show-TickleEvent 并为事件指定不同的天数。如果我想要对象,那么我可以使用 Get-TickleEvent 函数,该函数将根据 ID 或名称等条件导入 csv 事件。该函数使用参数集,我根据参数集创建一个过滤器脚本块。
Switch ($pscmdlet.ParameterSetName) {
"ID" {
Write-Verbose "by ID"
$filter = [scriptblock]::Create("`$_.id -in `$id") }
"Name" {
Write-Verbose "by Name"
$filter = [scriptblock]::Create("`$_.Event -like `$Name") }
"Expired" {
Write-Verbose "by Expiration"
$filter = [scriptblock]::Create("`$_.Date -lt (Get-Date)") }
"All" {
Write-Verbose "All"
$filter = [scriptblock]::Create("`$_ -match '\w+'") }
}
当我导入 CSV 文件时,我将类型添加到属性中,否则所有内容都将是字符串,然后将每个对象通过管道传输到我的过滤器。
#import CSV and cast properties to correct type
Import-CSV -Path $Path |
Select @{Name="ID";Expression={[int]$_.ID}},
@{Name="Date";Expression={[datetime]$_.Date}},
Event,Comment | where $Filter | Sort Date
这些对象非常有用,因为它们可以通过管道传输到 Set-TickleEvent 来修改事件名称、日期或注释等值。或者我可以通过管道发送到Remove-TickleEvent 来删除条目。删除过程本质上是查找 CSV 文件中所有不以正确 id 开头的行,并使用相同的名称创建一个新文件。
if ($pscmdlet.ShouldProcess(($myEvent | Out-String))) {
#find all lines in the CSV except the matching event
$otherevents = Get-Content -path $Path | where {$_ -notmatch "^""$($myevent.id)"}
#remove it
$otherevents | Out-File -FilePath $Path -Encoding ascii
}
最后,在意外删除事件文件后,我添加了一个简单的备份功能,将 CSV 文件复制到同一目录,但文件扩展名为 .BAK。您可以指定备用路径,但默认为 WindowsPowerShell 文件夹。
希望我不会再错过重要的事件,当然假设我将它们添加到我的备忘文件中。我将让您使用 Add-TickleEvent 来了解其工作原理,或者您始终可以使用记事本修改 CSV 文件。
如果你真的使用这个,我希望你能告诉我。
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视] 黑道中人 Alto Knights(2025)剧情 犯罪 历史 电影
[古装剧] [七侠五义][全75集][WEB-MP4/76G][国语无字][1080P][焦恩俊经典]
[实用软件] 虚拟手机号 电话 验证码 注册
[电视剧] 安眠书店/你 第五季 You Season 5 (2025) 【全10集】
[电视剧] 棋士(2025) 4K 1080P【全22集】悬疑 犯罪 王宝强 陈明昊
[软件合集] 25年6月5日 精选软件22个
[软件合集] 25年6月4日 精选软件36个
[短剧] 2025年06月04日 精选+付费短剧推荐33部
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[实用软件] 虚拟手机号 电话 验证码 注册
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag