英文:
PowerShell script isfailing when executing from Intune
问题
I'm here to provide a Chinese translation of the content you provided. Here's the translated version:
我在尝试通过Intune在我的设备之外的设备上运行PowerShell脚本时遇到了困难。背景如下。
我希望在每个用户的工作站上以其凭据的上下文部署公司图像,因为这些图像将用作Microsoft Teams的背景。因此,它们需要部署到C:\Users\<user name>\AppData\Roaming\Microsoft\Teams\Backgrounds\Uploads(请注意,我们没有Teams Premium许可证,因此无法通过Teams Admin Center部署图像)。
当我在本地执行我的脚本,无论是在我的笔记本电脑上还是在其他笔记本电脑上,脚本都可以正常执行,并且图像被部署到正确的目录。这已经使用本地管理员帐户和非特权用户帐户进行了测试。
但是,当我将脚本添加并分配给要部署的组时,它在我的机器上继续正常工作,但在其他笔记本电脑上出现以下错误 -
***PS> TerminatingError(Import-Module):“无法加载文件或程序集'System.Management.Automation,Version=7.2.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35'或其任何依赖项。系统找不到指定的文件。”***
***Connect-PnPOnline:在模块'PnP.PowerShell'中找到了'Connect-PnPOnline'命令,但无法加载该模块。有关更多信息,请运行'Import-Module PnP.PowerShell'。***
请注意,如果我将脚本复制到另一台笔记本电脑并使用非管理员权限登录,它会成功运行,因此我知道本机环境支持该脚本。仅当通过Intune执行时才会失败。到目前为止,我已经在互联网上搜索,但没有找到解决方案。
这是我正在执行的脚本 -
```text
#用于上传Teams公司背景的脚本
Start-Transcript -Path "C:\Apps\Teams_Background.log"
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Scope CurrentUser -Force
Unregister-PSRepository -Name PSGallery
Register-PSRepository -Default
#确定是否需要安装PnP.PowerShell模块
try {
Write-Host "尝试查找PnP.PowerShell模块"
$PnPModule = Get-InstalledModule -Name PnP.PowerShell -Verbose:$false
if ($null -ne $PnPModule) {
Write-Host "检测到身份验证模块"
}
}
catch [System.Exception] {
Write-Host "无法检测到PnP.PowerShell模块,尝试从PSGallery安装"
try {
#安装PnP.PowerShell模块
Install-Module -Name PnP.PowerShell -Scope CurrentUser -Force -Confirm:$false -Verbose:$false
Write-Host "成功安装PnP.PowerShell"
}
catch [System.Exception] {
Write-Host "尝试安装PnP.PowerShell模块时发生错误。错误消息:$($_.Exception.Message)" ; break
}
}
#确定是否需要安装Az.Keyvault模块
try {
Write-Host "尝试查找Az.Keyvault模块"
$AzModule = Get-InstalledModule -Name Az.Keyvault -Verbose:$false
if ($null -ne $AzModule) {
Write-Host "检测到身份验证模块"
}
}
catch [System.Exception] {
Write-Host "无法检测到Az.Keyvault模块,尝试从PSGallery安装"
try {
#安装Az模块
Install-Module -Name Az.Keyvault -Scope CurrentUser -Force -Confirm:$false -Verbose:$false
Write-Host "成功安装Az.Keyvault"
}
catch [System.Exception] {
Write-Host "尝试安装Az.Keyvault模块时发生错误。错误消息:$($_.Exception.Message)" ; break
}
}
#为SharePoint站点和库设置变量
$tenant = "company.onmicrosoft.com"
$siteURL = "https://company.sharepoint.com/library"
$applicationID = "xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$library = "/Shared Documents/Templates & Branding/MS Teams Backgrounds"
$filename1 = "Teams_Background_file.jpg"
$filename2 = "Teams_Background_file_thumb.jpg"
$sourcepath1 = Join-Path $library $filename1
$sourcepath2 = Join-Path $library $filename2
$pathdir = Join-Path $ENV:Appdata "Microsoft\Teams\Backgrounds\Uploads"
#如果Backgrounds\Uploads文件夹不存在,则创建
If (!(Test-Path $pathdir)) {
New-Item -ItemType Directory -Path $pathdir -Force | Out-Null
}
#指定Key Vault名称和证书名称
$VaultName = "SharePointAuthentication"
$certName = "Certname"
#建立与Azure的连接
$clientID = "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx"
$key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
$SecurePassword = $key | ConvertTo-SecureString -AsPlainText -Force
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $clientID, $SecurePassword
$tenantID = "xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$library = "/Shared Documents/Templates & Branding"
Connect-AzAccount -Credential $cred -TenantId $tenantID -ServicePrincipal
#获取存储在KeyVault中的证书
$secret = Get-AzKeyVaultSecret -VaultName $vaultName -Name $certName
# $secretValueText = ($secret.SecretValue | ConvertFrom-SecureString -AsPlainText )
$bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secret.SecretValue)
$secretValueText = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)
#连接到PnP
Connect-PnPOnline -Url $siteUrl -ClientId $applicationID -Tenant $tenant -CertificateBase64Encoded $secretValueText
#将文件上传到库
Get-PnPFile $
<details>
<summary>英文:</summary>
I'm running into difficulties running a PowerShell script via Intune on devices outside of my own. The background is as follows.
I want to deploy corporate images to each users workstation, under the context of their credentials, as the images are to be used as Microsoft Teams backgrounds. As such, they need to be deployed to C:\\Users\\\<user name\>\\AppData\\Roaming \\Microsoft\\Teams\\Backgrounds\\Uploads (note that we do not have Teams Premium licenses, so cannot deploy images via the Teams Admin Center).
When I execute my script locally, either on my laptop or another laptop, the script executes fine and the images are deployed to the correct directory. This has been tested using both a local admin account and also a non-privileged user account.
When I add the script and assign it to a group for deployment, it continues to work fine on my machine, but is failing on other laptops with the following error -
***PS\>TerminatingError(Import-Module): "Could not load file or assembly 'System.Management.Automation, Version=7.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified."***
***Connect-PnPOnline : The 'Connect-PnPOnline' command was found in the module 'PnP.PowerShell', but the module could not be loaded. For more information, run 'Import-Module PnP.PowerShell'.***
Note that if I copy the script to another laptop and log in with non-admin rights, it runs successfully, so I know the native environment supports the script. It only fails when executing through Intune. I've trawled the Internet with no solution found to date.
Here is the script I am executing -
#Script for uploading Teams Corporate Backgrounds
Start-Transcript -Path "C:\Apps\Teams_Background.log"
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Scope CurrentUser -Force
Unregister-PSRepository -Name PSGallery
Register-PSRepository -Default
Determine if the PnP.PowerShell module needs to be installed
try {
Write-Host "Attempting to locate PnP.PowerShell module"
$PnPModule = Get-InstalledModule -Name PnP.PowerShell -Verbose:$false
if ($null -ne $PnPModule) {
Write-Host "Authentication module detected"
}
}
catch [System.Exception] {
Write-Host "Unable to detect PnP.PowerShell module, attempting to install from PSGallery"
try {
# Install PnP.PowerShell module
Install-Module -Name PnP.PowerShell -Scope CurrentUser -Force -Confirm:$false -Verbose:$false
Write-Host "Successfully installed PnP.PowerShell"
}
catch [System.Exception] {
Write-Host "An error occurred while attempting to install PnP.PowerShell module. Error message: $($_.Exception.Message)" ; break
}
}
Determine if the Az.Keyvault module needs to be installed
try {
Write-Host "Attempting to locate Az.Keyvault module"
$AzModule = Get-InstalledModule -Name Az.Keyvault -Verbose:$false
if ($null -ne $AzModule) {
Write-Host "Authentication module detected"
}
}
catch [System.Exception] {
Write-Host "Unable to detect Az.Keyvault module, attempting to install from PSGallery"
try {
# Install Az module
Install-Module -Name Az.Keyvault -Scope CurrentUser -Force -Confirm:$false -Verbose:$false
Write-Host "Successfully installed Az.Keyvault"
}
catch [System.Exception] {
Write-Host "An error occurred while attempting to install Az.Keyvault module. Error message: $($_.Exception.Message)" ; break
}
}
Set variables for the SharePoint site and library
$tenant = "company.onmicrosoft.com"
$siteURL = "https://company.sharepoint.com/library"
$applicationID = "xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$library = "/Shared Documents/Templates & Branding/MS Teams Backgrounds"
$filename1 = "Teams_Background_file.jpg"
$filename2 = "Teams_Background_file_thumb.jpg"
$sourcepath1 = Join-Path $library $filename1
$sourcepath2 = Join-Path $library $filename2
$pathdir = Join-Path $ENV:Appdata "Microsoft\Teams\Backgrounds\Uploads"
#Create Backgrounds\Uploads folder if it doesn't exist
If (!(Test-Path $pathdir)) {
New-Item -ItemType Directory -Path $pathdir -Force | Out-Null
}
Specify Key Vault Name and Certificate Name
$VaultName = "SharePointAuthentication"
$certName = "Certname"
Establish a connection to Azure
$clientID = "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx"
$key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
$SecurePassword = $key | ConvertTo-SecureString -AsPlainText -Force
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $clientID, $SecurePassword
$tenantID = "xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$library = "/Shared Documents/Templates & Branding"
Connect-AzAccount -Credential $cred -TenantId $tenantID -ServicePrincipal
Get certificate stored in KeyVault
$secret = Get-AzKeyVaultSecret -VaultName $vaultName -Name $certName
$secretValueText = ($secret.SecretValue | ConvertFrom-SecureString -AsPlainText )
$bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secret.SecretValue)
$secretValueText = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)
connect to PnP
Connect-PnPOnline -Url $siteUrl -ClientId $applicationID -Tenant $tenant -CertificateBase64Encoded $secretValueText
Upload the files to the library
Get-PnPFile $sourcepath1 -Path $pathdir -Filename $filename1 -AsFile -Force
Get-PnPFile $sourcepath2 -Path $pathdir -Filename $filename2 -AsFile -Force
Disconnect from SharePoint Online
Disconnect-PnPOnline
Stop-Transcript
On my machine I have run this successfully with both Windows PowerShell Desktop version 5.1.22621.963 and PowerShell Core version 7.3.3
It appears that the way it executes when deployed via Intune is different to the way it runs locally, but I'm at a loss to understand why.
Any help will be greatly appreciated.
</details>
# 答案1
**得分**: 4
升级到 PnP Powershell 2.1.1 之后出现了相同的错误。
我回退到版本 1.12.0,之后我的代码又正常运行了。
Uninstall-Module PnP.Powershell
Install-Module -Name PnP.PowerShell -RequiredVersion 1.12.0
<details>
<summary>英文:</summary>
Had the same error after upgrading to PnP Powershell 2.1.1 this morning.
I went back to version 1.12.0 and, after that, my code was working again.
Uninstall-Module PnP.Powershell
Install-Module -Name PnP.PowerShell -RequiredVersion 1.12.0
</details>
# 答案2
**得分**: 1
我已将所需的图像文件放在一个可访问的网站上,然后只是使用 **Invoke-WebRequest**,这消除了与 **PnP.Powershell** 的任何交互需求,解决了我的问题。
<details>
<summary>英文:</summary>
I've ended up putting the images files I need on an accessible web site and just using **Invoke-WebRequest** instead. This has removed the need for any interaction with **PnP.Powershell** and solved my problem.
</details>
# 答案3
**得分**: 0
I had this exact issue in our Azure DevOps release pipeline as of yesterday (worked fine for months before that).
根据此文档(https://github.com/pnp/powershell/blob/dev/MIGRATE-1.0-to-2.0.md),PnP.PowerShell的v2.x仅与PowerShell 7.2.x或更高版本正确配合使用。
I was able to fix the pipeline by forcing our PowerShell task to run with PowerShell Core instead of the default V5.
我通过在"高级"选项下设置此复选框来强制使用PowerShell Core而不是默认的V5,来修复了管道:
If you're using YAML pipelines the correct syntax would be something like this:
如果您正在使用YAML管道,正确的语法应该是这样的:
```yaml
- task: PowerShell@2
displayName: RunWithPs7
inputs:
pwsh: true
filePath: '$(Pipeline.Workspace)\s\PowerShell\GetVersion.ps1'
Maybe Intune has an option as well to enforce using this version?
也许Intune也有一个选项来强制使用这个版本?
英文:
I had this exact issue in our Azure DevOps release pipeline as of yesterday (worked fine for months before that).
According to this documentation (https://github.com/pnp/powershell/blob/dev/MIGRATE-1.0-to-2.0.md) v2.x of PnP.PowerShell only works correctly with PowerShell 7.2.x or later.
I was able to fix the pipeline by forcing our PowerShell task to run with PowerShell Core instead of the default V5.
I did this by updating the task by setting this checkbox under Advanced:
If you're using YAML pipelines the correct syntax would be something like this:
- task: PowerShell@2
displayName: RunWithPs7
inputs:
pwsh: true
filePath: '$(Pipeline.Workspace)\s\PowerShell\GetVersion.ps1'
(source for YAML sample: https://microsoft-bitools.blogspot.com/2021/02/devops-snack-change-powershell-version.html)
Maybe Intune has an option as well to enforce using this version?
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论