我的任务是自动化每月的维护。基本上我需要将 xmla 文件中的日期值编辑到下个月。
这是 XMLA 文件中的相关部分:
<Process xmlns="http://schemas.microsoft.com/analysisservices/2003/engine">
<Type>ProcessFull</Type>
<Object>
<DatabaseID>OLAPQA</DatabaseID>
<CubeID>Model</CubeID>
<MeasureGroupID>TRANSACTIONS</MeasureGroupID>
<PartitionID>TRANSACTIONS 201410</PartitionID>
</Object>
</Process>
<Process xmlns="http://schemas.microsoft.com/analysisservices/2003/engine">
<Type>ProcessFull</Type>
<Object>
<DatabaseID>OLAPQA</DatabaseID>
<CubeID>Model</CubeID>
<MeasureGroupID>TRANSACTIONS</MeasureGroupID>
<PartitionID>TRANSACTIONS 201411</PartitionID>
</Object>
</Process>
<Process xmlns="http://schemas.microsoft.com/analysisservices/2003/engine">
<Type>ProcessFull</Type>
<Object>
<DatabaseID>OLAPQA</DatabaseID>
<CubeID>Model</CubeID>
<MeasureGroupID>TRANSACTIONS</MeasureGroupID>
<PartitionID>TRANSACTIONS 201412</PartitionID>
</Object>
</Process>
我需要使用以下逻辑编写一个 windows powershell 脚本:
- 获取当前日期并验证它是否是该月的第一天
- 如果是,则计算前一天(为了计算前 2 年/月值(
- 搜索 XMLA 文件以将以前的年/月组合替换为新值
我已经解决了数字 1 和 2,但我在解决数字 3 时遇到了一些麻烦。
这是我的代码:
$con = Get-Content .Process2Periods.xmla
$con | % { $_.Replace("((Get-Date).AddMonths(-2) | Get-Date -Format "yyyyMM")", ("((Get-Date).AddMonths(-1) | Get-Date -Format "yyyyMM")") } | Set-Content .Process2Periods.xmla
我是如何做到这一点的,运行以下代码,它的工作方式与上面的代码不同:
$con = Get-Content .Process2Periods.xmla
$con | % { $_.Replace("201410", "201411") } | Set-Content .Process2Periods.xmla
我的问题是如何使这种动态化,而不是将值硬编码到脚本中。我每个月都需要它来更改三个标签。代码适用于字符串值,但我如何将某些代码的输出作为字符串值?我应该使用变量吗?
提前谢谢。
试试这个:
$con = Get-Content C:Process2Periods.xmla
$lastMonth = (Get-Date).AddMonths(-1) | Get-Date -Format "yyyyMM"
$thisMonth = (Get-Date) | Get-Date -Format "yyyyMM"
$con | % { $_.Replace($lastMonth,$thisMonth) } | Set-Content .Process2Periods.xmla
我很难理解您要做的事情的逻辑。我看到您正在将每个值的月份更改一个。因此,我假设您将在每个日期的月份每月的第一天增加一个月。我不明白数字 2,因为我没有看到你对天数进行任何操纵。
$path = .Process2Periods.xmla
$xmla = Get-Content -Path $path
$now = (Get-Date -day 1) #-day 1 is there to trigger next If. Remove for prod.
If($now.Day -eq 1){
# It is the first of the month.
$xmla | ForEach-Object{
# Output each line back to the variable while editting the found dates
If($_ -match "<PartitionID>D+(d{6})</PartitionID>"){
$_ -replace $matches[1], ('{0:yyyyMM}' -f [datetime]::ParseExact($matches[1],"yyyyMM", $null).AddMonths(1))
} Else {
$_
}
}
} | Set-Content $path
获取文件的内容并通过foreach-Object
循环处理它们,假设它是每月的第一天。输出要输出的正常行,但如果找到带有PartitionID
标签的行,我们将拉出 6 位数字。接下来,我们将操作字符串写回具有更新日期的输出。有趣的部分是匹配和替换的工作原理,我将尝试分解。
-
matches[1]
包含匹配项中的第一个捕获组。在我们的例子中是 6 位数字。 - 获取这些数字并使用解析精确将它们转换为
[datetime]
对象。 - 将月份增加 1
- 获取新日期并使用
-f
参数将其转换回"yyyyMM"字符串。 - 将匹配的数字替换为新日期。
确定出了什么问题,这不是你的意图,但就像我之前提到的,我真的不明白你在做什么。如果你能理解我应该做什么,我认为我们可以用你真正想要的东西来做这件事。